public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { DynamicMetaObject self = target; DynamicMetaObject res = null; if (self.NeedsDeferral()) { return(MyDefer(self)); } IPythonConvertible convertible = target as IPythonConvertible; if (convertible != null) { res = convertible.BindConvert(this); } else if (res == null) { res = BindConvert(self); } if (_retObject) { res = new DynamicMetaObject( AstUtils.Convert(res.Expression, typeof(object)), res.Restrictions ); } return(res); }
/// <summary> /// Transforms an invoke member into a Python GetMember/Invoke. The caller should /// verify that the given attribute is not resolved against a normal .NET class /// before calling this. If it is a normal .NET member then a fallback InvokeMember /// is preferred. /// </summary> internal static DynamicMetaObject /*!*/ GenericInvokeMember(InvokeMemberBinder /*!*/ action, ValidationInfo valInfo, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args) { if (target.NeedsDeferral()) { return(action.Defer(args)); } return(AddDynamicTestAndDefer(action, action.FallbackInvoke( new DynamicMetaObject( Binders.Get( PythonContext.GetCodeContext(action), PythonContext.GetPythonContext(action), typeof(object), action.Name, target.Expression ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target) ), args, null ), args, valInfo )); }
public override DynamicMetaObject FallbackDeleteMember(DynamicMetaObject self, DynamicMetaObject errorSuggestion) { if (self.NeedsDeferral()) { return Defer(self); } return Context.Binder.DeleteMember(Name, self, new PythonOverloadResolverFactory(_context.Binder, AstUtils.Constant(Context.SharedContext))); }
public override DynamicMetaObject FallbackDeleteMember(DynamicMetaObject self, DynamicMetaObject errorSuggestion) { if (self.NeedsDeferral()) { return Defer(self); } return Binder.Binder.DeleteMember(Name, self, AstUtils.Constant(Binder.Context)); }
public override DynamicMetaObject FallbackDeleteMember(DynamicMetaObject self, DynamicMetaObject errorSuggestion) { if (self.NeedsDeferral()) { return(Defer(self)); } return(Context.Binder.DeleteMember(Name, self, new PythonOverloadResolverFactory(_context.Binder, AstUtils.Constant(Context.SharedContext)), errorSuggestion)); }
/// <summary> /// Fallback - performs the default binding operation if the object isn't recognized /// as being invokable. /// </summary> internal DynamicMetaObject /*!*/ Fallback(Expression codeContext, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args) { if (target.NeedsDeferral()) { return(Defer(args)); } return(PythonProtocol.Call(this, target, args) ?? Context.Binder.Create(Signature, target, args, codeContext) ?? Context.Binder.Call(Signature, new PythonOverloadResolverFactory(Context.Binder, codeContext), target, args)); }
public override DynamicMetaObject FallbackSetMember(DynamicMetaObject self, DynamicMetaObject value, DynamicMetaObject onBindingError) { if (self.NeedsDeferral()) { return Defer(self, value); } #if !SILVERLIGHT DynamicMetaObject com; if (System.Dynamic.ComBinder.TryBindSetMember(this, self, value, out com)) { return com; } #endif return Binder.Binder.SetMember(Name, self, value, Ast.Constant(Binder.Context)); }
internal static DynamicMetaObject FallbackWorker(PythonContext context, DynamicMetaObject /*!*/ self, DynamicMetaObject /*!*/ codeContext, string name, GetMemberOptions options, DynamicMetaObjectBinder action, DynamicMetaObject errorSuggestion) { if (self.NeedsDeferral()) { return(action.Defer(self)); } PythonOverloadResolverFactory resolverFactory = new PythonOverloadResolverFactory(context.Binder, codeContext.Expression); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "FallbackGet"); bool isNoThrow = ((options & GetMemberOptions.IsNoThrow) != 0) ? true : false; Type limitType = self.GetLimitType(); if (limitType == typeof(DynamicNull) || PythonBinder.IsPythonType(limitType)) { // look up in the PythonType so that we can // get our custom method names (e.g. string.startswith) PythonType argType = DynamicHelpers.GetPythonTypeFromType(limitType); // if the name is defined in the CLS context but not the normal context then // we will hide it. if (argType.IsHiddenMember(name)) { DynamicMetaObject baseRes = PythonContext.GetPythonContext(action).Binder.GetMember( name, self, resolverFactory, isNoThrow, errorSuggestion ); Expression failure = GetFailureExpression(limitType, self, name, isNoThrow, action); return(BindingHelpers.FilterShowCls(codeContext, action, baseRes, failure)); } } var res = PythonContext.GetPythonContext(action).Binder.GetMember(name, self, resolverFactory, isNoThrow, errorSuggestion); // Default binder can return something typed to boolean or int. // If that happens, we need to apply Python's boxing rules. if (res.Expression.Type.IsValueType) { res = new DynamicMetaObject( AstUtils.Convert(res.Expression, typeof(object)), res.Restrictions ); } return(res); }
public override DynamicMetaObject FallbackSetMember(DynamicMetaObject self, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { if (self.NeedsDeferral()) { return(Defer(self, value)); } #if FEATURE_COM DynamicMetaObject com; if (Microsoft.Scripting.ComInterop.ComBinder.TryBindSetMember(this, self, BindingHelpers.GetComArgument(value), out com)) { return(com); } #endif return(Context.Binder.SetMember(Name, self, value, errorSuggestion, new PythonOverloadResolverFactory(_context.Binder, AstUtils.Constant(Context.SharedContext)))); }
public static DynamicMetaObject/*!*/ Operation(UnaryOperationBinder/*!*/ operation, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback UnaryOperator " + " " + operation.Operation + " " + arg.LimitType.FullName); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString()); DynamicMetaObject[] args = new[] { arg }; if (arg.NeedsDeferral()) { return operation.Defer(arg); } ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args); DynamicMetaObject res = null; Type retType = typeof(object); switch (operation.Operation) { case ExpressionType.UnaryPlus: res = BindingHelpers.AddPythonBoxing(MakeUnaryOperation(operation, arg, "__pos__", errorSuggestion)); break; case ExpressionType.Negate: res = BindingHelpers.AddPythonBoxing(MakeUnaryOperation(operation, arg, "__neg__", errorSuggestion)); break; case ExpressionType.OnesComplement: res = BindingHelpers.AddPythonBoxing(MakeUnaryOperation(operation, arg, "__invert__", errorSuggestion)); break; case ExpressionType.Not: res = MakeUnaryNotOperation(operation, arg, typeof(object), errorSuggestion); break; case ExpressionType.IsFalse: res = MakeUnaryNotOperation(operation, arg, typeof(bool), errorSuggestion); retType = typeof(bool); break; case ExpressionType.IsTrue: res = PythonProtocol.ConvertToBool(operation, arg); retType = typeof(bool); break; default: res = TypeError(operation, "unknown operation: " + operation.ToString(), args); break; } return BindingHelpers.AddDynamicTestAndDefer(operation, res, args, valInfo, retType); }
public static DynamicMetaObject Operation(UnaryOperationBinder operation, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback UnaryOperator " + " " + operation.Operation + " " + arg.LimitType.FullName); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString()); DynamicMetaObject[] args = new[] { arg }; if (arg.NeedsDeferral()) return operation.Defer(arg); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args); TotemOperationKind? toOperator = null; Type retType = typeof(object); bool box = true; bool inverse = false; switch (operation.Operation) { case ExpressionType.UnaryPlus: toOperator = TotemOperationKind.Positive; break; case ExpressionType.Negate: toOperator = TotemOperationKind.Negate; break; case ExpressionType.OnesComplement: toOperator = TotemOperationKind.OnesComplement; break; case ExpressionType.Not: toOperator = TotemOperationKind.Not; box = false; break; case ExpressionType.IsFalse: toOperator = TotemOperationKind.IsFalse; box = false; retType = typeof(bool); break; case ExpressionType.IsTrue: toOperator = TotemOperationKind.IsFalse; box = false; retType = typeof(bool); inverse = true; break; } DynamicMetaObject res = null; if (toOperator != null) res = MakeUnaryOperation(operation, args[0], toOperator.Value, errorSuggestion, retType); else res = operation.FallbackUnaryOperation(arg); if (inverse) { res = new DynamicMetaObject( Expression.Condition( res.Expression, Utils.Constant(ScriptingRuntimeHelpers.False), Utils.Constant(ScriptingRuntimeHelpers.True) ), res.Restrictions ); } if (box) { res = BindingHelpers.AddTotemBoxing(res); } return BindingHelpers.AddDynamicTestAndDefer(operation, res, args, valInfo, retType); }
internal static DynamicMetaObject Call(DynamicMetaObjectBinder /*!*/ call, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args) { Assert.NotNull(call, args); Assert.NotNullItems(args); if (target.NeedsDeferral()) { return(call.Defer(ArrayUtils.Insert(target, args))); } foreach (DynamicMetaObject mo in args) { if (mo.NeedsDeferral()) { RestrictTypes(args); return(call.Defer( ArrayUtils.Insert(target, args) )); } } DynamicMetaObject self = target.Restrict(target.GetLimitType()); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target); PythonType pt = DynamicHelpers.GetPythonType(target.Value); PythonContext pyContext = PythonContext.GetPythonContext(call); // look for __call__, if it's present dispatch to it. Otherwise fall back to the // default binder PythonTypeSlot callSlot; if (!typeof(Delegate).IsAssignableFrom(target.GetLimitType()) && pt.TryResolveSlot(pyContext.SharedContext, "__call__", out callSlot)) { ConditionalBuilder cb = new ConditionalBuilder(call); callSlot.MakeGetExpression( pyContext.Binder, PythonContext.GetCodeContext(call), self, GetPythonType(self), cb ); if (!cb.IsFinal) { cb.FinishCondition(GetCallError(call, self)); } Expression[] callArgs = ArrayUtils.Insert( PythonContext.GetCodeContext(call), cb.GetMetaObject().Expression, DynamicUtils.GetExpressions(args) ); Expression body = DynamicExpression.Dynamic( PythonContext.GetPythonContext(call).Invoke( BindingHelpers.GetCallSignature(call) ), typeof(object), callArgs ); body = Ast.TryFinally( Ast.Block( Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPushFrame)), Ast.Constant(pyContext)), body ), Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPopFrame))) ); return(BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))), args, valInfo )); } return(null); }
/// <summary> /// Transforms an invoke member into a Python GetMember/Invoke. The caller should /// verify that the given attribute is not resolved against a normal .NET class /// before calling this. If it is a normal .NET member then a fallback InvokeMember /// is preferred. /// </summary> internal static DynamicMetaObject/*!*/ GenericInvokeMember(InvokeMemberBinder/*!*/ action, ValidationInfo valInfo, DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args) { if (target.NeedsDeferral()) { return action.Defer(args); } return AddDynamicTestAndDefer(action, action.FallbackInvoke( new DynamicMetaObject( Binders.Get( BinderState.GetCodeContext(action), BinderState.GetBinderState(action), typeof(object), action.Name, target.Expression ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target) ), args, null ), args, valInfo ); }
/// <summary> /// Fallback - performs the default binding operation if the object isn't recognized /// as being invokable. /// </summary> internal DynamicMetaObject/*!*/ Fallback(Expression codeContext, DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args) { if (target.NeedsDeferral()) { return Defer(args); } return PythonProtocol.Call(this, target, args) ?? Binder.Binder.Create(Signature, new ParameterBinderWithCodeContext(Binder.Binder, codeContext), target, args) ?? Binder.Binder.Call(Signature, new ParameterBinderWithCodeContext(Binder.Binder, codeContext), target, args); }
/// <summary> /// Transforms a call into a Python GetMember/Invoke. This isn't quite the correct semantic as /// we shouldn't be returning Python members (e.g. object.__repr__) to non-Python callers. This /// can go away as soon as all of the classes implement the full fidelity of the protocol /// </summary> internal static DynamicMetaObject/*!*/ GenericCall(InvokeMemberBinder/*!*/ action, DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args) { if (target.NeedsDeferral()) { return action.Defer(args); } return new DynamicMetaObject( Invoke( BinderState.GetCodeContext(action), BinderState.GetBinderState(action), typeof(object), GetCallSignature(action), ArrayUtils.Insert( Binders.Get( BinderState.GetCodeContext(action), BinderState.GetBinderState(action), typeof(object), action.Name, target.Expression ), DynamicUtils.GetExpressions(args) ) ), BindingRestrictions.Combine(args).Merge(target.Restrict(target.GetLimitType()).Restrictions) ); }