/// <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)); }
/// <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)); }