private DynamicMetaObject TryPythonConversion(DynamicMetaObjectBinder conversion, Type type) { if (!type.IsEnum) { switch (type.GetTypeCode()) { case TypeCode.Object: if (type == typeof(Complex)) { return(MakeConvertRuleForCall(conversion, type, this, "__complex__", "ConvertToComplex", (() => MakeConvertRuleForCall(conversion, type, this, "__float__", "ConvertToFloat", (() => FallbackConvert(conversion)), (x) => Ast.Call(null, typeof(PythonOps).GetMethod(nameof(PythonOps.ConvertFloatToComplex)), x))), (x) => x)); } else if (type == typeof(BigInteger)) { return(MakeConvertRuleForCall(conversion, type, this, "__long__", "ConvertToLong")); } else if (type == typeof(IEnumerable)) { return(PythonConversionBinder.ConvertToIEnumerable(conversion, Restrict(Value.GetType()))); } else if (type == typeof(IEnumerator)) { return(PythonConversionBinder.ConvertToIEnumerator(conversion, Restrict(Value.GetType()))); } else if (type.IsSubclassOf(typeof(Delegate))) { return(MakeDelegateTarget(conversion, type, Restrict(Value.GetType()))); } break; case TypeCode.Int32: if (!typeof(Extensible <int>).IsAssignableFrom(LimitType)) { return(MakeConvertRuleForCall(conversion, type, this, "__int__", "ConvertToInt")); } break; case TypeCode.Double: return(MakeConvertRuleForCall(conversion, type, this, "__float__", "ConvertToFloat")); case TypeCode.Boolean: return(PythonProtocol.ConvertToBool( conversion, this )); case TypeCode.String: if (!typeof(Extensible <string>).IsAssignableFrom(LimitType)) { return(MakeConvertRuleForCall(conversion, type, this, "__str__", "ConvertToString")); } break; } } return(null); }
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 )); }
internal DynamicMetaObject /*!*/ InvokeFallback(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, CallSignature sig, DynamicMetaObject errorSuggestion) { return (PythonProtocol.Call(this, target, args) ?? Context.Binder.Create(sig, target, args, AstUtils.Constant(_context.SharedContext)) ?? Context.Binder.Call(sig, errorSuggestion, new PythonOverloadResolverFactory(Context.Binder, AstUtils.Constant(_context.SharedContext)), target, args)); }
private DynamicMetaObject /*!*/ MakeToBoolConversion(DynamicMetaObject /*!*/ self) { DynamicMetaObject res; if (self.HasValue) { self = self.Restrict(self.GetRuntimeType()); } // Optimization: if we already boxed it to a bool, and now // we're unboxing it, remove the unnecessary box. if (self.Expression.NodeType == ExpressionType.Convert && self.Expression.Type == typeof(object)) { var convert = (UnaryExpression)self.Expression; if (convert.Operand.Type == typeof(bool)) { return(new DynamicMetaObject(convert.Operand, self.Restrictions)); } } if (self.GetLimitType() == typeof(DynamicNull)) { // None has no __nonzero__ and no __len__ but it's always false res = MakeNoneToBoolConversion(self); } else if (self.GetLimitType() == typeof(bool)) { // nothing special to convert from bool to bool res = self; } else if (typeof(IStrongBox).IsAssignableFrom(self.GetLimitType())) { // Explictly block conversion of References to bool res = MakeStrongBoxToBoolConversionError(self); } else if (self.GetLimitType().IsPrimitive || self.GetLimitType().IsEnum) { // optimization - rather than doing a method call for primitives and enums generate // the comparison to zero directly. res = MakePrimitiveToBoolComparison(self); } else { // anything non-null that doesn't fall under one of the above rules is true. So we // fallback to the base Python conversion which will check for __nonzero__ and // __len__. The fallback is handled by our ConvertTo site binder. return (PythonProtocol.ConvertToBool(this, self) ?? new DynamicMetaObject( AstUtils.Constant(true), self.Restrictions )); } return(res); }
DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) { switch (action.Operation) { case PythonOperationKind.CallSignatures: return(PythonProtocol.MakeCallSignatureOperation(this, Value.Template.Targets)); } return(null); }
DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Operation " + action.Operation); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunc Operation"); switch (action.Operation) { case PythonOperationKind.CallSignatures: return PythonProtocol.MakeCallSignatureOperation(this, Value.Targets); } return null; }
/// <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 FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion) { #if !SILVERLIGHT DynamicMetaObject com; if (Microsoft.Scripting.ComInterop.ComBinder.TryBindGetIndex(this, target, BindingHelpers.GetComArguments(indexes), out com)) { return(com); } #endif return(PythonProtocol.Index(this, PythonIndexType.GetItem, ArrayUtils.Insert(target, indexes), errorSuggestion)); }
public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { if (target is IPythonOperable op) { DynamicMetaObject res = op.BindOperation(this, ArrayUtils.Insert(target, args)); if (res != null) { return(res); } } return(PythonProtocol.Operation(this, ArrayUtils.Insert(target, args))); }
public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion) { #if FEATURE_COM DynamicMetaObject com; if (Microsoft.Scripting.ComInterop.ComBinder.TryBindSetIndex(this, target, BindingHelpers.GetComArguments(indexes), BindingHelpers.GetComArgument(value), out com)) { return(com); } #endif DynamicMetaObject[] finalArgs = new DynamicMetaObject[indexes.Length + 2]; finalArgs[0] = target; for (int i = 0; i < indexes.Length; i++) { finalArgs[i + 1] = indexes[i]; } finalArgs[finalArgs.Length - 1] = value; return(PythonProtocol.Index(this, PythonIndexType.SetItem, finalArgs, errorSuggestion)); }
public override DynamicMetaObject /*!*/ BindSetIndex(SetIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes, DynamicMetaObject /*!*/ value) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass SetIndex" + indexes.Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass SetIndex"); return(PythonProtocol.Index(binder, PythonIndexType.SetItem, ArrayUtils.Insert(this, ArrayUtils.Append(indexes, value)))); }
public override DynamicMetaObject /*!*/ BindUnaryOperation(UnaryOperationBinder /*!*/ binder) { return(PythonProtocol.Operation(binder, this, null)); }
public override DynamicMetaObject /*!*/ BindDeleteIndex(DeleteIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes) { return(PythonProtocol.Index(binder, PythonIndexType.DeleteItem, ArrayUtils.Insert(this, indexes))); }
public override DynamicMetaObject /*!*/ BindSetIndex(SetIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes, DynamicMetaObject /*!*/ value) { return(PythonProtocol.Index(binder, PythonIndexType.SetItem, ArrayUtils.Insert(this, ArrayUtils.Append(indexes, value)))); }
public override DynamicMetaObject FallbackDeleteIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion) { return(PythonProtocol.Index(this, PythonIndexType.DeleteItem, ArrayUtils.Insert(target, indexes), errorSuggestion)); }
public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { return(PythonProtocol.Index(this, PythonIndexType.DeleteSlice, ArrayUtils.Insert(target, args))); }
public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) { return(PythonProtocol.Operation(this, target, arg, errorSuggestion)); }
public override DynamicMetaObject /*!*/ BindUnaryOperation(UnaryOperationBinder /*!*/ binder) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass UnaryOperation" + binder.Operation); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass UnaryOperation"); return(PythonProtocol.Operation(binder, this, null)); }
public override DynamicMetaObject /*!*/ BindDeleteIndex(DeleteIndexBinder /*!*/ binder, DynamicMetaObject /*!*/[] /*!*/ indexes) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass DeleteIndex" + indexes.Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass DeleteIndex"); return(PythonProtocol.Index(binder, PythonIndexType.DeleteItem, ArrayUtils.Insert(this, indexes))); }