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