/// <summary>
        /// Helper for falling back - if we have a base object fallback to it first (which can
        /// then fallback to the calling site), otherwise fallback to the calling site.
        /// </summary>
        private DynamicMetaObject /*!*/ Fallback(DynamicMetaObjectBinder /*!*/ action, DynamicMetaObject codeContext)
        {
            if (_baseMetaObject != null)
            {
                IPythonGetable ipyget = _baseMetaObject as IPythonGetable;
                if (ipyget != null)
                {
                    PythonGetMemberBinder gmb = action as PythonGetMemberBinder;
                    if (gmb != null)
                    {
                        return(ipyget.GetMember(gmb, codeContext));
                    }
                }

                GetMemberBinder gma = action as GetMemberBinder;
                if (gma != null)
                {
                    return(_baseMetaObject.BindGetMember(gma));
                }

                return(_baseMetaObject.BindGetMember(
                           PythonContext.GetPythonContext(action).CompatGetMember(
                               GetGetMemberName(action),
                               false
                               )
                           ));
            }

            return(GetMemberFallback(this, action, codeContext));
        }
Example #2
0
        /// <summary>
        /// Python's Invoke is a non-standard action.  Here we first try to bind through a Python
        /// internal interface (IPythonInvokable) which supports CallSigantures.  If that fails
        /// and we have an IDO then we translate to the DLR protocol through a nested dynamic site -
        /// this includes unsplatting any keyword / position arguments.  Finally if it's just a plain
        /// old .NET type we use the default binder which supports CallSignatures.
        /// </summary>
        public override DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            Debug.Assert(args.Length == 1);
            Debug.Assert(args[0].GetLimitType() == typeof(CodeContext));

            // we don't have CodeContext if an IDO falls back to us when we ask them to produce the Call
            DynamicMetaObject cc  = args[0];
            IPythonGetable    icc = target as IPythonGetable;

            if (icc != null)
            {
                // get the member using our interface which also supports CodeContext.
                return(icc.GetMember(this, cc));
            }
            else if (target.Value is IDynamicMetaObjectProvider)
            {
                return(GetForeignObject(target));
            }
#if FEATURE_COM
            else if (Microsoft.Scripting.ComInterop.ComBinder.IsComObject(target.Value))
            {
                return(GetForeignObject(target));
            }
#endif
            return(Fallback(target, cc));
        }