Пример #1
0
        /// <summary>
        /// Provides default binding for performing a call on the specified meta objects.
        /// </summary>
        /// <param name="signature">The signature describing the call</param>
        /// <param name="target">The meta object to be called.</param>
        /// <param name="args">
        /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction.
        /// </param>
        /// <param name="resolverFactory">Overload resolver factory.</param>
        /// <param name="errorSuggestion">The result should the object be uncallable.</param>
        /// <returns>A MetaObject representing the call or the error.</returns>
        public DynamicMetaObject Call(CallSignature signature, DynamicMetaObject errorSuggestion, OverloadResolverFactory resolverFactory,ClrMethod method, DynamicMetaObject target, params DynamicMetaObject[] args)
        {
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.RequiresNotNull(resolverFactory, "resolverFactory");

            TargetInfo targetInfo = GetTargetInfo(method, target, args);

            if (targetInfo != null)
            {
                // we're calling a well-known MethodBase
                DynamicMetaObject res = MakeMetaMethodCall(signature, resolverFactory, targetInfo);
                if (res.Expression.Type.IsValueType)
                {
                    if (res.Expression.Type == Types.Void)
                        res = new DynamicMetaObject(
                            Expression.Block(Types.Object[0],
                                res.Expression,
                                Expression.Constant(null)),
                            res.Restrictions
                        );
                    else
                        res = new DynamicMetaObject(
                            Expression.Convert(res.Expression, typeof(object)),
                            res.Restrictions
                    );
                }

                return res;
            }
            else
            {
                // we can't call this object
                return errorSuggestion ?? MakeCannotCallRule(target, target.GetLimitType());
            }
        }
Пример #2
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;
 }
Пример #3
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;
        }
Пример #4
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) {
                    MethodInfo dc = GetDelegateCtor(t);

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

                return CallMethod(
                    new PythonOverloadResolver(
                        this,
                        args,
                        signature,
                        contextExpression
                    ), 
                    CompilerHelpers.GetConstructors(t, PrivateBinding), 
                    BindingRestrictions.Empty
                );
            }

            return null;
        }
Пример #5
0
        public DefaultOverloadResolver(ActionBinder binder, IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType)
            : base(binder) {
            ContractUtils.RequiresNotNullItems(args, "args");

            Debug.Assert((callType == CallTypes.ImplicitInstance ? 1 : 0) + signature.ArgumentCount == args.Count);
            _args = args;
            _signature = signature;
            _callType = callType;
        }
Пример #6
0
        /// <summary>
        /// Provides default binding for performing a call on the specified meta objects.
        /// </summary>
        /// <param name="signature">The signature describing the call</param>
        /// <param name="target">The meta object to be called.</param>
        /// <param name="args">
        /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction.
        /// </param>
        /// <param name="resolverFactory">Overload resolver factory.</param>
        /// <returns>A MetaObject representing the call or the error.</returns>
        public DynamicMetaObject Call(CallSignature signature, OverloadResolverFactory resolverFactory, DynamicMetaObject target, params DynamicMetaObject[] args) {
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.RequiresNotNull(resolverFactory, "resolverFactory");

            TargetInfo targetInfo = GetTargetInfo(signature, target, args);

            if (targetInfo != null) {
                // we're calling a well-known MethodBase
                return MakeMetaMethodCall(signature, resolverFactory, targetInfo);
            } else {
                // we can't call this object
                return MakeCannotCallRule(target, target.GetLimitType());
            }
        }
Пример #7
0
        /// <summary>
        /// Provides default binding for performing a call on the specified meta objects.
        /// </summary>
        /// <param name="signature">The signature describing the call</param>
        /// <param name="target">The meta object to be called.</param>
        /// <param name="args">
        /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction.
        /// </param>
        /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param>
        /// <returns>A MetaObject representing the call or the error.</returns>
        public DynamicMetaObject Call(CallSignature signature, ParameterBinder parameterBinder, DynamicMetaObject target, params DynamicMetaObject[] args) {
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder");

            TargetInfo targetInfo = GetTargetInfo(signature, target, args);

            if (targetInfo != null) {
                // we're calling a well-known MethodBase
                return MakeMetaMethodCall(signature, parameterBinder, targetInfo);
            } else {
                // we can't call this object
                return MakeCannotCallRule(target, target.LimitType);
            }
        }
Пример #8
0
        public static Expression/*!*/ Invoke(BinderState/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) {
            PythonInvokeBinder invoke = new PythonInvokeBinder(binder, signature);
            switch(args.Length) {
                case 0: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext());
                case 1: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0]);
                case 2: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1]);
                case 3: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1], args[2]);
                default:
                    return Ast.Dynamic(
                        invoke,
                        resultType,
                        new ReadOnlyCollection<Expression>(ArrayUtils.Insert(AstUtils.CodeContext(), args))
                    );
            }

        }
Пример #9
0
        private DynamicMetaObject MakeMetaMethodCall(CallSignature signature, OverloadResolverFactory resolverFactory, TargetInfo targetInfo) {
            BindingRestrictions restrictions = BindingRestrictions.Combine(targetInfo.Arguments).Merge(targetInfo.Restrictions);
            if (targetInfo.Instance != null) {
                restrictions = targetInfo.Instance.Restrictions.Merge(restrictions);
            }

            DynamicMetaObject[] args;
            CallTypes callType;
            if (targetInfo.Instance != null) {
                args = ArrayUtils.Insert(targetInfo.Instance, targetInfo.Arguments);
                callType = CallTypes.ImplicitInstance;
            } else {
                args = targetInfo.Arguments;
                callType = CallTypes.None;
            }

            return CallMethod(resolverFactory.CreateOverloadResolver(args, signature, callType), targetInfo.Targets, restrictions);
        }
Пример #10
0
        public MetaObject Create(CallSignature signature, ParameterBinderWithCodeContext parameterBinder, MetaObject target, MetaObject[] 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 MetaObject(
                        Ast.Call(null, dc, parameterBinder.ContextExpression, args[0].Expression),
                        target.Restrictions.Merge(Restrictions.GetInstanceRestriction(target.Expression, target.Value))
                    );
                }

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

            return null;
        }
Пример #11
0
        /// <summary>
        /// Provides default binding for performing a call on the specified meta objects.
        /// </summary>
        /// <param name="signature">The signature describing the call</param>
        /// <param name="target">The meta object to be called.</param>
        /// <param name="args">
        /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction.
        /// </param>
        /// <param name="resolverFactory">Overload resolver factory.</param>
        /// <returns>A MetaObject representing the call or the error.</returns>
        public DynamicMetaObject Call(CallSignature signature, OverloadResolverFactory resolverFactory, DynamicMetaObject target, params DynamicMetaObject[] args) {
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.RequiresNotNull(resolverFactory, "resolverFactory");

            TargetInfo targetInfo = GetTargetInfo(target, args);

            if (targetInfo != null) {
                // we're calling a well-known MethodBase
                DynamicMetaObject res =  MakeMetaMethodCall(signature, resolverFactory, targetInfo);
                if (res.Expression.Type.IsValueType) {
                    res = new DynamicMetaObject(
                        AstUtils.Convert(res.Expression, typeof(object)),
                        res.Restrictions
                    );
                }

                return res;
            } else {
                // we can't call this object
                return MakeCannotCallRule(target, target.GetLimitType());
            }
        }
Пример #12
0
        private DynamicMetaObject MakeMetaMethodCall(CallSignature signature, ParameterBinder parameterBinder, TargetInfo targetInfo) {
            BindingRestrictions restrictions = BindingRestrictions.Combine(targetInfo.Arguments).Merge(targetInfo.Restrictions);
            if (targetInfo.Instance != null) {
                restrictions = targetInfo.Instance.Restrictions.Merge(restrictions);
            }

            if (targetInfo.Instance != null) {
                return CallInstanceMethod(
                    parameterBinder,
                    targetInfo.Targets,
                    targetInfo.Instance,
                    targetInfo.Arguments,
                    signature,
                    restrictions
                );
            }

            return CallMethod(
                parameterBinder,
                targetInfo.Targets,
                targetInfo.Arguments,
                signature,
                restrictions);
        }
Пример #13
0
 public override DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType)
 {
     if (signature.ArgumentCount < args.Count && callType != CallTypes.ImplicitInstance) //FIX: when CallTypes != ImplicitInstance, remove the first arg (self)
     {
         //The self arg is added in `DefaultBinder.GetTargetInfo`
         args = new List <DynamicMetaObject>(args.Skip(1));
     }
     return(new TjsOverloadResolver(_binder, args, signature, callType));
 }
Пример #14
0
 public static Expression/*!*/ Invoke(Expression codeContext, PythonContext/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) {
     return Ast.Dynamic(
         binder.Invoke(
             signature
         ),
         resultType,
         ArrayUtils.Insert(codeContext, args)
     );
 }
Пример #15
0
        private static Expression GetArgumentExpression(CallSignature signature, ArgumentType kind, ref int unusedCount, DynamicMetaObject/*!*/[]/*!*/ args) {
            int index = signature.IndexOf(kind);
            if (index != -1) {
                unusedCount--;
                return args[index].Expression;
            }

            return AstUtils.Constant(null);
        }
Пример #16
0
        /// <summary>
        /// Attempts to bind to an operator Call method.
        /// </summary>
        private TargetInfo TryGetOperatorTargets(DynamicMetaObject self, DynamicMetaObject[] args, object target, CallSignature signature) {
            MethodBase[] targets;

            Type targetType = CompilerHelpers.GetType(target);

            MemberGroup callMembers = GetMember(OldCallAction.Make(this, signature), targetType, "Call");
            List<MethodBase> callTargets = new List<MethodBase>();
            foreach (MemberTracker mi in callMembers) {
                if (mi.MemberType == TrackerTypes.Method) {
                    MethodInfo method = ((MethodTracker)mi).Method;
                    if (method.IsSpecialName) {
                        callTargets.Add(method);
                    }
                }
            }

            Expression instance = null;
            if (callTargets.Count > 0) {
                targets = callTargets.ToArray();
                instance = Ast.Convert(self.Expression, CompilerHelpers.GetType(target));
                return new TargetInfo(null, ArrayUtils.Insert(self, args), targets);
            }

            return null;
        }
Пример #17
0
 public override LangElement Call(Span span, LangElement nameExpr, CallSignature signature, TypeRef typeRef)
 => CountLE(base.Call(span, nameExpr, signature, typeRef));
Пример #18
0
        private Expression/*!*/ MakeCheckSelf(DynamicMetaObjectBinder/*!*/ binder, CallSignature signature, DynamicMetaObject/*!*/[]/*!*/ args) {
            ArgumentType firstArgKind = signature.GetArgumentKind(0);

            Expression res;
            if (firstArgKind == ArgumentType.Simple || firstArgKind == ArgumentType.Instance) {
                res = CheckSelf(binder, AstUtils.Convert(Expression, typeof(Method)), args[0].Expression);
            } else if (firstArgKind != ArgumentType.List) {
                res = CheckSelf(binder, AstUtils.Convert(Expression, typeof(Method)), AstUtils.Constant(null));
            } else {
                // list, check arg[0] and then return original list.  If not a list,
                // or we have no items, then check against null & throw.
                res = CheckSelf(
                    binder,
                    AstUtils.Convert(Expression, typeof(Method)),
                    Ast.Condition(
                        Ast.AndAlso(
                            Ast.TypeIs(args[0].Expression, typeof(IList<object>)),
                            Ast.NotEqual(
                                Ast.Property(
                                    Ast.Convert(args[0].Expression, typeof(ICollection)),
                                    typeof(ICollection).GetProperty("Count")
                                ),
                                AstUtils.Constant(0)
                            )
                        ),
                        Ast.Call(
                            Ast.Convert(args[0].Expression, typeof(IList<object>)),
                            typeof(IList<object>).GetMethod("get_Item"),
                            AstUtils.Constant(0)
                        ),
                        AstUtils.Constant(null)
                    )
                );
            }

            return res;
        }
Пример #19
0
        public MSAst.Expression/*!*/ Invoke(Type/*!*/ resultType, CallSignature signature, params MSAst.Expression/*!*/[]/*!*/ args) {
            PythonInvokeBinder invoke = BinderState.Invoke(signature);
            switch (args.Length) {
                case 0: return Globals.Dynamic(invoke, resultType, LocalContext);
                case 1: return Globals.Dynamic(invoke, resultType, LocalContext, args[0]);
                case 2: return Globals.Dynamic(invoke, resultType, LocalContext, args[0], args[1]);
                case 3: return Globals.Dynamic(invoke, resultType, LocalContext, args[0], args[1], args[2]);
                default:
                    return Globals.Dynamic(
                        invoke,
                        resultType,
                        ArrayUtils.Insert(LocalContext, args)
                    );
            }

        }
Пример #20
0
 // method call:
 public PythonOverloadResolver(PythonBinder binder, IList <DynamicMetaObject> args, CallSignature signature, Expression codeContext)
     : this(binder, args, signature, CallTypes.None, codeContext)
 {
 }
Пример #21
0
 // method call:
 public PythonOverloadResolver(PythonBinder binder, IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType, Expression codeContext)
     : base(binder, args, signature, callType)
 {
     Assert.NotNull(codeContext);
     _context = codeContext;
 }
Пример #22
0
 public override LangElement Attribute(Span span, TypeRef classref, CallSignature signature = default(CallSignature))
 => CountLE(base.Attribute(span, classref, signature));
Пример #23
0
 public override DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType)
 {
     return(new PythonOverloadResolver(_binder, args, signature, callType, _codeContext));
 }
Пример #24
0
 public override LangElement Call(Span span, TranslatedQualifiedName name, CallSignature signature, LangElement memberOfOpt)
 => CountLE(base.Call(span, name, signature, memberOfOpt));
Пример #25
0
 public override LangElement Call(Span span, Name name, Span nameSpan, CallSignature signature, TypeRef typeRef)
 => CountLE(base.Call(span, name, nameSpan, signature, typeRef));
Пример #26
0
 public override LangElement Call(Span span, LangElement nameExpr, CallSignature signature, LangElement memberOfOpt)
 => CountLE(base.Call(span, nameExpr, signature, memberOfOpt));
Пример #27
0
        /// <summary>
        /// Makes test for param arrays and param dictionary parameters.
        /// </summary>
        private static BindingRestrictions MakeSplatTests(CallTypes callType, CallSignature signature, bool testTypes, IList<DynamicMetaObject> args) {
            BindingRestrictions res = BindingRestrictions.Empty;

            if (signature.HasListArgument()) {
                res = MakeParamsArrayTest(callType, signature, testTypes, args);
            }

            if (signature.HasDictionaryArgument()) {
                res = res.Merge(MakeParamsDictionaryTest(args, testTypes));
            }

            return res;
        }
Пример #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);
        }
Пример #29
0
 public ArgumentValues(CallSignature signature, DynamicMetaObject/*!*/ self, DynamicMetaObject/*!*/[]/*!*/ args) {
     Self = self;
     Signature = signature;
     Arguments = args;
 }
Пример #30
0
 public PythonInvokeBinder(PythonContext /*!*/ context, CallSignature signature)
 {
     _context   = context;
     _signature = signature;
 }
Пример #31
0
 // TODO: Rename Call to Invoke, obsolete Call
 // TODO: Invoke overloads should also take CallInfo objects to simplify use for languages which don't need CallSignature features.
 /// <summary>
 /// Provides default binding for performing a call on the specified meta objects.
 /// </summary>
 /// <param name="signature">The signature describing the call</param>
 /// <param name="target">The meta object to be called.</param>
 /// <param name="args">
 /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction.
 /// </param>
 /// <returns>A MetaObject representing the call or the error.</returns>
 public DynamicMetaObject Call(CallSignature signature, DynamicMetaObject target, params DynamicMetaObject[] args)
 {
     return Call(signature, new DefaultOverloadResolverFactory(this), target, args);
 }
Пример #32
0
 public LightThrowBinder(PythonContext /*!*/ context, CallSignature signature)
     : base(context, signature)
 {
 }
Пример #33
0
 public abstract DefaultOverloadResolver CreateOverloadResolver(IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType);
Пример #34
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);
            }
                       ));
        }
Пример #35
0
 /// <summary>
 /// Creates statistic for ambient function.
 /// </summary>
 public FunctionStatistic(SymbolAtom namespaceName, SymbolAtom name, CallSignature callSignature, StringTable stringTable)
     : this(GetFullName(namespaceName, name), callSignature, stringTable)
 {
 }
Пример #36
0
 internal static CallSignature GetReversedSignature(CallSignature signature)
 {
     return(new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple))));
 }
Пример #37
0
        private readonly CallSignature _signature;      // the call signature for the call

        public LateBoundInitBinder(PythonType type, CallSignature signature)
        {
            _newType   = type;
            _signature = signature;
        }
Пример #38
0
 internal DynamicMetaObject /*!*/ InvokeFallback(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, CallSignature sig, DynamicMetaObject errorSuggestion)
 {
     return
         (PythonProtocol.Call(this, target, args) ??
          Context.Binder.Create(sig, target, args, AstUtils.Constant(_context.SharedContext)) ??
          Context.Binder.Call(sig, errorSuggestion, new PythonOverloadResolverFactory(Context.Binder, AstUtils.Constant(_context.SharedContext)), target, args));
 }
Пример #39
0
        private static Expression NoInitCheckNoArgs(CallSignature signature, DynamicMetaObject self, DynamicMetaObject[] args) {
            int unusedCount = args.Length;

            Expression dictExpr = GetArgumentExpression(signature, ArgumentType.Dictionary, ref unusedCount, args);
            Expression listExpr = GetArgumentExpression(signature, ArgumentType.List, ref unusedCount, args);

            if (signature.IsSimple || unusedCount > 0) {
                if (args.Length > 0) {
                    return Ast.Call(
                        typeof(PythonOps).GetMethod("OldClassMakeCallError"),
                        self.Expression
                    );
                }

                return AstUtils.Constant(null);
            }

            return Ast.Call(
                typeof(PythonOps).GetMethod("OldClassCheckCallError"),
                self.Expression,
                dictExpr,
                listExpr
            );
        }
Пример #40
0
 public static Expression /*!*/ Invoke(Expression codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, CallSignature signature, params Expression /*!*/[] /*!*/ args)
 {
     return(DynamicExpression.Dynamic(
                binder.Invoke(
                    signature
                    ),
                resultType,
                ArrayUtils.Insert(codeContext, args)
                ));
 }
Пример #41
0
 public TjsOverloadResolver(TjsBinder binder, IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType) : base(binder, args, signature, callType)
 {
 }
Пример #42
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 = DynamicExpression.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
                       ));
        }
Пример #43
0
 private static BindingRestrictions MakeSplatTests(CallTypes callType, CallSignature signature, IList<DynamicMetaObject> args) {
     return MakeSplatTests(callType, signature, false, args);
 }
Пример #44
0
 public ArgumentValues(CallSignature signature, DynamicMetaObject /*!*/ self, DynamicMetaObject /*!*/[] /*!*/ args)
 {
     Self      = self;
     Signature = signature;
     Arguments = args;
 }
Пример #45
0
        /// <summary>
        /// Pulls out the right argument to build the splat test.  MakeParamsTest makes the actual test.
        /// </summary>
        private static BindingRestrictions MakeParamsArrayTest(CallTypes callType, CallSignature signature, bool testTypes, IList<DynamicMetaObject> args) {
            int listIndex = signature.IndexOf(ArgumentType.List);
            Debug.Assert(listIndex != -1);
            if (callType == CallTypes.ImplicitInstance) {
                listIndex++;
            }

            return MakeParamsTest(args[listIndex], testTypes);
        }
Пример #46
0
 /// <summary>
 /// Creates statistic for a user-defined function or to a member function.
 /// </summary>
 public FunctionStatistic(List <SymbolAtom> fullName, CallSignature callSignature, StringTable stringTable)
     : this(GetFullNameAsString(fullName, callSignature, stringTable))
 {
 }
Пример #47
0
 public override DefaultOverloadResolver CreateOverloadResolver(IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType)
 {
     return new DefaultOverloadResolver(_binder, args, signature, callType);
 }
Пример #48
0
 /// <inheritdoc />
 public override string ToDebugString()
 {
     return($"{CallSignature.ToDebugString()} => {Body?.ToDebugString()}");
 }
Пример #49
0
        private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder/*!*/ callAction, DynamicMetaObject/*!*/[] args) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method");

            CallSignature signature = BindingHelpers.GetCallSignature(callAction);
            DynamicMetaObject self = Restrict(typeof(Method));
            BindingRestrictions restrictions = self.Restrictions;

            DynamicMetaObject func = GetMetaFunction(self);
            DynamicMetaObject call;

            if (Value.im_self == null) {
                // restrict to null self (Method is immutable so this is an invariant test)
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Ast.Equal(
                            GetSelfExpression(self),
                            AstUtils.Constant(null)
                        )
                    )
                );

                if (args.Length == 0) {
                    // this is an error, we pass null which will throw the normal error
                    call = new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("MethodCheckSelf"),
                            PythonContext.GetCodeContext(callAction),
                            self.Expression,
                            AstUtils.Constant(null)
                        ),
                        restrictions
                    );
                } else {
                    // this may or may not be an error
                    call = new DynamicMetaObject(
                        Ast.Block(
                            MakeCheckSelf(callAction, signature, args),
                            Ast.Dynamic(
                                PythonContext.GetPythonContext(callAction).Invoke(
                                    BindingHelpers.GetCallSignature(callAction)
                                ),
                                typeof(object),
                                ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(ArrayUtils.Insert(func, args)))
                            )
                        ),
                        BindingRestrictions.Empty
                    );
                    /*call = func.Invoke(callAction, ArrayUtils.Insert(func, args));
                    call =  new MetaObject(
                        Ast.Comma(
                            Ast.Call(
                                typeof(PythonOps).GetMethod("MethodCheckSelf"),
                                self.Expression,
                                args[0].Expression
                            ),
                            call.Expression
                        ),
                        call.Restrictions                        
                    );*/
                }
            } else {
                // restrict to non-null self (Method is immutable so this is an invariant test)
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Ast.NotEqual(
                            GetSelfExpression(self),
                            AstUtils.Constant(null)
                        )
                    )
                );

                DynamicMetaObject im_self = GetMetaSelf(self);
                DynamicMetaObject[] newArgs = ArrayUtils.Insert(func, im_self, args);
                CallSignature newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos()));


                call = new DynamicMetaObject(
                    Ast.Dynamic(
                        PythonContext.GetPythonContext(callAction).Invoke(
                            newSig
                        ),
                        typeof(object),
                        ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs))
                    ),
                    BindingRestrictions.Empty
                );

                /*
                call = func.Invoke(
                    new CallBinder(
                        PythonContext.GetBinderState(callAction),
                        newSig
                    ),
                    newArgs
                );*/
            }

            if (call.HasValue) {
                return new DynamicMetaObject(
                    call.Expression,
                    restrictions.Merge(call.Restrictions),
                    call.Value
                );
            } else {
                return new DynamicMetaObject(
                    call.Expression,
                    restrictions.Merge(call.Restrictions)
                );
            }
        }
Пример #50
0
 /// <summary>
 /// Creates ambient function.
 /// </summary>
 public static FunctionLikeExpression CreateAmbient(SymbolAtom name, CallSignature signature, InvokeAmbient fun, [NotNull] FunctionStatistic statistics)
 {
     Contract.Requires(name.IsValid);
     return(new FunctionLikeExpression(name, signature, fun, default(LineInfo), statistics));
 }
Пример #51
0
 /// <summary>
 /// Provides default binding for performing a call on the specified meta objects.
 /// </summary>
 /// <param name="signature">The signature describing the call</param>
 /// <param name="target">The meta object to be called.</param>
 /// <param name="args">
 /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction.
 /// </param>
 /// <param name="resolverFactory">Overload resolver factory.</param>
 /// <returns>A MetaObject representing the call or the error.</returns>
 public DynamicMetaObject Call(CallSignature signature, OverloadResolverFactory resolverFactory, DynamicMetaObject target, params DynamicMetaObject[] args)
 {
     return Call(signature, null, resolverFactory, target, args);
 }
Пример #52
0
 /// <summary>
 /// Creates a callable expression for the ambient function.
 /// </summary>
 /// <param name="name">Name of the function if applicable</param>
 /// <param name="callSignature">Signature of the lambda.</param>
 /// <param name="ambient">Delegate to serve as lambda's body.</param>
 /// <param name="location">Location of delegates definition.</param>
 /// <param name="statistic">Function invocation statistics.</param>
 private FunctionLikeExpression(SymbolAtom name, [NotNull] CallSignature callSignature, InvokeAmbient ambient, LineInfo location, [NotNull] FunctionStatistic statistic)
     : this(name, callSignature : callSignature, body : null, captures : 0, locals : callSignature.Parameters.Count, fun : ambient, location : location, statistic : statistic)
 {
     Contract.Requires(callSignature != null);
     Contract.Requires(ambient != null);
 }
Пример #53
0
 internal static CallSignature GetReversedSignature(CallSignature signature) {
     return new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple)));
 }
Пример #54
0
        private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder /*!*/ callAction, DynamicMetaObject /*!*/[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method");

            CallSignature       signature    = BindingHelpers.GetCallSignature(callAction);
            DynamicMetaObject   self         = Restrict(typeof(Method));
            BindingRestrictions restrictions = self.Restrictions;

            DynamicMetaObject func = GetMetaFunction(self);
            DynamicMetaObject call;

            if (Value.im_self == null)
            {
                // restrict to null self (Method is immutable so this is an invariant test)
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Ast.Equal(
                            GetSelfExpression(self),
                            AstUtils.Constant(null)
                            )
                        )
                    );

                if (args.Length == 0)
                {
                    // this is an error, we pass null which will throw the normal error
                    call = new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("MethodCheckSelf"),
                            PythonContext.GetCodeContext(callAction),
                            self.Expression,
                            AstUtils.Constant(null)
                            ),
                        restrictions
                        );
                }
                else
                {
                    // this may or may not be an error
                    call = new DynamicMetaObject(
                        Ast.Block(
                            MakeCheckSelf(callAction, signature, args),
                            DynamicExpression.Dynamic(
                                PythonContext.GetPythonContext(callAction).Invoke(
                                    BindingHelpers.GetCallSignature(callAction)
                                    ).GetLightExceptionBinder(callAction.SupportsLightThrow()),
                                typeof(object),
                                ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(ArrayUtils.Insert(func, args)))
                                )
                            ),
                        BindingRestrictions.Empty
                        );

                    /*call = func.Invoke(callAction, ArrayUtils.Insert(func, args));
                     * call =  new MetaObject(
                     *  Ast.Comma(
                     *      Ast.Call(
                     *          typeof(PythonOps).GetMethod("MethodCheckSelf"),
                     *          self.Expression,
                     *          args[0].Expression
                     *      ),
                     *      call.Expression
                     *  ),
                     *  call.Restrictions
                     * );*/
                }
            }
            else
            {
                // restrict to non-null self (Method is immutable so this is an invariant test)
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Ast.NotEqual(
                            GetSelfExpression(self),
                            AstUtils.Constant(null)
                            )
                        )
                    );

                DynamicMetaObject   im_self = GetMetaSelf(self);
                DynamicMetaObject[] newArgs = ArrayUtils.Insert(func, im_self, args);
                CallSignature       newSig  = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos()));


                call = new DynamicMetaObject(
                    DynamicExpression.Dynamic(
                        PythonContext.GetPythonContext(callAction).Invoke(
                            newSig
                            ).GetLightExceptionBinder(callAction.SupportsLightThrow()),
                        typeof(object),
                        ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs))
                        ),
                    BindingRestrictions.Empty
                    );

                /*
                 * call = func.Invoke(
                 *  new CallBinder(
                 *      PythonContext.GetBinderState(callAction),
                 *      newSig
                 *  ),
                 *  newArgs
                 * );*/
            }

            if (call.HasValue)
            {
                return(new DynamicMetaObject(
                           call.Expression,
                           restrictions.Merge(call.Restrictions),
                           call.Value
                           ));
            }
            else
            {
                return(new DynamicMetaObject(
                           call.Expression,
                           restrictions.Merge(call.Restrictions)
                           ));
            }
        }
Пример #55
0
        /// <summary>
        /// Gets a TargetInfo object for performing a call on this object.  
        /// 
        /// If this object is a delegate we bind to the Invoke method.
        /// If this object is a MemberGroup or MethodGroup we bind to the methods in the member group.
        /// If this object is a BoundMemberTracker we bind to the methods with the bound instance.
        /// If the underlying type has defined an operator Call method we'll bind to that method.
        /// </summary>
        private TargetInfo GetTargetInfo(CallSignature signature, DynamicMetaObject target, DynamicMetaObject[] args) {
            Debug.Assert(target.HasValue);
            object objTarget = target.Value;

            return
                TryGetDelegateTargets(target, args, objTarget as Delegate) ??
                TryGetMemberGroupTargets(target, args, objTarget as MemberGroup) ??
                TryGetMethodGroupTargets(target, args, objTarget as MethodGroup) ??
                TryGetBoundMemberTargets(target, args, objTarget as BoundMemberTracker) ??
                TryGetOperatorTargets(target, args, target, signature);
        }
Пример #56
0
 public static CallInfo GetCallInfoForCallSignature(CallSignature signature)
 {
     return(new CallInfo(signature.ArgumentCount, signature.GetArgumentNames()));
 }
Пример #57
0
 /// <summary>
 /// Provides default binding for performing a call on the specified meta objects.
 /// </summary>
 /// <param name="signature">The signature describing the call</param>
 /// <param name="target">The object to be called</param>
 /// <param name="args">
 /// Additional meta objects are the parameters for the call as specified by the CallSignature in the CallAction.
 /// </param>
 /// <returns>A MetaObject representing the call or the error.</returns>
 public DynamicMetaObject Call(CallSignature signature, DynamicMetaObject target, params DynamicMetaObject[] args) {
     return Call(signature, new ParameterBinder(this), target, args);
 }
Пример #58
0
 public abstract DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType);
Пример #59
0
 public override DefaultOverloadResolver CreateOverloadResolver(IList <DynamicMetaObject> args, CallSignature signature, CallTypes callType)
 {
     return(new DefaultOverloadResolver(
                _context.DefaultBinderState.Binder,
                args,
                signature,
                callType));
 }
Пример #60
0
 public TjsInvokeBinder(TjsContext context, CallSignature signature) : base(Binders.GetCallInfoForCallSignature(signature))
 {
     _context  = context;
     Signature = signature;
 }