TryGetStaticFunction() static private method

Tries to get the BuiltinFunction for the given name on the type of the provided MetaObject. Succeeds if the MetaObject is a BuiltinFunction or BuiltinMethodDescriptor.
static private TryGetStaticFunction ( PythonContext state, string op, DynamicMetaObject mo, IronPython.Runtime.Types.BuiltinFunction &function ) : bool
state PythonContext
op string
mo System.Dynamic.DynamicMetaObject
function IronPython.Runtime.Types.BuiltinFunction
return bool
Esempio n. 1
0
        /// <summary>
        /// Tries to get a MethodBinder associated with 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(PythonContext /*!*/ state, DynamicMetaObject /*!*/[] /*!*/ types, string op, string 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 PythonOverloadResolver(
                state.Binder,
                types,
                new CallSignature(types.Length),
                AstUtils.Constant(state.SharedContext)
                );

            if (xBf == null)
            {
                if (yBf == null)
                {
                    binder = null;
                    bt     = null;
                }
                else
                {
                    declaringType = DynamicHelpers.GetPythonTypeFromType(yBf.DeclaringType);
                    binder        = state.Binder.CallMethod(mc, yBf.Targets, BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt);
                }
            }
            else
            {
                if (yBf == null)
                {
                    declaringType = DynamicHelpers.GetPythonTypeFromType(xBf.DeclaringType);
                    binder        = state.Binder.CallMethod(mc, xBf.Targets, BindingRestrictions.Empty, null, 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(), BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt);

                    foreach (MethodBase mb in yBf.Targets)
                    {
                        if (bt.Overload.ReflectionInfo == 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);
        }