static private GetValidationInfo ( ) : |
||
return |
private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ action, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args) { ValidationInfo typeTest = BindingHelpers.GetValidationInfo(this, Value.PythonType); if (Value is PythonType) { PythonContext context = PythonContext.GetPythonContext(action); // optimization for meta classes. Don't dispatch to type.__call__ if it's inherited, // instead produce a normal type call rule. PythonTypeSlot callSlot, typeCallSlot; if (Value.PythonType.TryResolveMixedSlot(context.SharedContext, "__call__", out callSlot) && TypeCache.PythonType.TryResolveSlot(context.SharedContext, "__call__", out typeCallSlot) && callSlot == typeCallSlot) { return(InvokeFallback(action, codeContext, args)); } } return(BindingHelpers.AddDynamicTestAndDefer( action, PythonProtocol.Call(action, this, args) ?? InvokeFallback(action, codeContext, args), args, typeTest )); }
public DynamicMetaObject ConvertWorker(DynamicMetaObjectBinder binder, Type type, Type retType, ConversionResultKind kind) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Conversion " + type.FullName); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Conversion"); ValidationInfo typeTest = BindingHelpers.GetValidationInfo(this, Value.PythonType); return(BindingHelpers.AddDynamicTestAndDefer( binder, TryPythonConversion(binder, type) ?? FallbackConvert(binder), new DynamicMetaObject[] { this }, typeTest, retType )); }
private DynamicMetaObject /*!*/ MakeConvertRuleForCall(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, string name, string returner, Func <DynamicMetaObject> fallback, Func <Expression, Expression> resultConverter) { PythonType pt = ((IPythonObject)self.Value).PythonType; PythonTypeSlot pts; CodeContext context = PythonContext.GetPythonContext(convertToAction).SharedContext; ValidationInfo valInfo = BindingHelpers.GetValidationInfo(this, pt); if (pt.TryResolveSlot(context, name, out pts) && !IsBuiltinConversion(context, pts, name, pt)) { ParameterExpression tmp = Ast.Variable(typeof(object), "func"); Expression callExpr = resultConverter( Ast.Call( PythonOps.GetConversionHelper(returner, GetResultKind(convertToAction)), Ast.Dynamic( PythonContext.GetPythonContext(convertToAction).InvokeNone, typeof(object), PythonContext.GetCodeContext(convertToAction), tmp ) ) ); if (typeof(Extensible <>).MakeGenericType(toType).IsAssignableFrom(self.GetLimitType())) { // if we're doing a conversion to the underlying type and we're an // Extensible<T> of that type: // if an extensible type returns it's self in a conversion, then we need // to actually return the underlying value. If an extensible just keeps // returning more instances of it's self a stack overflow occurs - both // behaviors match CPython. callExpr = AstUtils.Convert(AddExtensibleSelfCheck(convertToAction, toType, self, callExpr), typeof(object)); } return(BindingHelpers.AddDynamicTestAndDefer( convertToAction, new DynamicMetaObject( Ast.Condition( MakeTryGetTypeMember( PythonContext.GetPythonContext(convertToAction), pts, self.Expression, tmp ), callExpr, AstUtils.Convert( ConversionFallback(convertToAction), typeof(object) ) ), self.Restrict(self.GetRuntimeType()).Restrictions ), new DynamicMetaObject[] { this }, valInfo, tmp )); } return(fallback()); }
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); }