internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name) { if (hasSelf) { args = ArrayUtils.RemoveFirst(args); } CallSignature sig = BindingHelpers.GetCallSignature(call); if (sig.HasDictionaryArgument()) { int index = sig.IndexOf(ArgumentType.Dictionary); DynamicMetaObject dict = args[index]; if (!(dict.Value is IDictionary) && dict.Value != null) { // The DefaultBinder only handles types that implement IDictionary. Here we have an // arbitrary user-defined mapping type. We'll convert it into a PythonDictionary // and then have an embedded dynamic site pass that dictionary through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)), codeContext, args[index].Expression, AstUtils.Constant(name) ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()), PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name) ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType())) )); } } if (sig.HasListArgument()) { int index = sig.IndexOf(ArgumentType.List); DynamicMetaObject list = args[index]; if (!(list.Value is IList <object>) && list.Value != null) { // The DefaultBinder only handles types that implement IList<object>. Here we have a // arbitrary user-defined sequence type. We'll convert it into a tuple and then have // an embedded dynamic site pass that tuple through to the default binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonTuple)), codeContext, args[index].Expression, AstUtils.Constant(name) ), BindingRestrictions.Empty ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), function.Restrictions.Merge( BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(list.Expression, list.GetLimitType())) ) )); } } return(null); }
public void BindSpecifiedPropertyWithDefaults() => AssertExperimental(() => { var label = new Label(); label.Bind(Label.TextColorProperty, nameof(viewModel.TextColor)); BindingHelpers.AssertBindingExists(label, Label.TextColorProperty, nameof(viewModel.TextColor)); });
/// <summary> /// Helper for generating the call to a builtin function. This is used for calls from built-in method /// descriptors and built-in functions w/ and w/o a bound instance. /// /// This provides all sorts of common checks on top of the call while the caller provides a delegate /// to do the actual call. The common checks include: /// check for generic-only methods /// reversed operator support /// transforming arguments so the default binder can understand them (currently user defined mapping types to PythonDictionary) /// returning NotImplemented from binary operators /// Warning when calling certain built-in functions /// /// </summary> /// <param name="call">The call binder we're doing the call for</param> /// <param name="codeContext">An expression which points to the code context</param> /// <param name="function">the meta object for the built in function</param> /// <param name="hasSelf">true if we're calling with an instance</param> /// <param name="args">The arguments being passed to the function</param> /// <param name="functionRestriction">A restriction for the built-in function, method desc, etc...</param> /// <param name="bind">A delegate to perform the actual call to the method.</param> internal DynamicMetaObject /*!*/ MakeBuiltinFunctionCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/ function, DynamicMetaObject /*!*/[] args, bool hasSelf, BindingRestrictions /*!*/ functionRestriction, Func <DynamicMetaObject /*!*/[] /*!*/, BindingResult /*!*/> bind) { DynamicMetaObject res = null; // if we have a user defined operator for **args then transform it into a PythonDictionary DynamicMetaObject translated = TranslateArguments(call, codeContext, new DynamicMetaObject(function.Expression, functionRestriction, function.Value), args, hasSelf, Name); if (translated != null) { return(translated); } // swap the arguments if we have a reversed operator if (IsReversedOperator) { ArrayUtils.SwapLastTwo(args); } // do the appropriate calling logic BindingResult result = bind(args); // validate the result BindingTarget target = result.Target; res = result.MetaObject; if (target.Overload != null && target.Overload.IsProtected) { // report an error when calling a protected member res = new DynamicMetaObject( BindingHelpers.TypeErrorForProtectedMember( target.Overload.DeclaringType, target.Overload.Name ), res.Restrictions ); } else if (IsBinaryOperator && args.Length == 2 && IsThrowException(res.Expression)) { // Binary Operators return NotImplemented on failure. res = new DynamicMetaObject( Ast.Property(null, typeof(PythonOps), nameof(PythonOps.NotImplemented)), res.Restrictions ); } else if (target.Overload != null) { // Add profiling information for this builtin function, if applicable if (call is IPythonSite pythonSite) { var pc = pythonSite.Context; if (pc.Options is PythonOptions po && po.EnableProfiler) { Profiler profiler = Profiler.GetProfiler(pc); res = new DynamicMetaObject( profiler.AddProfiling(res.Expression, target.Overload.ReflectionInfo), res.Restrictions ); } } } // add any warnings that are applicable for calling this function WarningInfo info; if (target.Overload != null && BindingWarnings.ShouldWarn(PythonContext.GetPythonContext(call), target.Overload, out info)) { res = info.AddWarning(codeContext, res); } // finally add the restrictions for the built-in function and return the result. res = new DynamicMetaObject( res.Expression, functionRestriction.Merge(res.Restrictions) ); // The function 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 = BindingHelpers.AddPythonBoxing(res); } else if (res.Expression.Type == typeof(void)) { res = new DynamicMetaObject( Expression.Block( res.Expression, Expression.Constant(null) ), res.Restrictions ); } return(res); }
/// <summary> /// target is the newly initialized value. /// args are the arguments to be passed to __init__ /// </summary> public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { DynamicMetaObject codeContext = target; CodeContext context = (CodeContext)codeContext.Value; target = args[0]; args = ArrayUtils.RemoveFirst(args); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target); Expression res; PythonType instType = DynamicHelpers.GetPythonType(target.Value); BindingRestrictions initRestrictions = BindingRestrictions.Empty; if (IronPython.Modules.Builtin.isinstance(target.Value, _newType) && NeedsInitCall((CodeContext)codeContext.Value, instType, args.Length)) { // resolve __init__ PythonTypeSlot init; instType.TryResolveSlot(context, "__init__", out init); if (init is PythonFunction) { // avoid creating the bound method, just invoke it directly Expression[] allArgs = new Expression[args.Length + 3]; allArgs[0] = codeContext.Expression; allArgs[1] = AstUtils.WeakConstant(init); allArgs[2] = target.Expression; for (int i = 0; i < args.Length; i++) { allArgs[3 + i] = args[i].Expression; } res = DynamicExpression.Dynamic( context.LanguageContext.Invoke(_signature.InsertArgument(Argument.Simple)), typeof(object), allArgs ); } else if (init is BuiltinMethodDescriptor || init is BuiltinFunction) { IList <MethodBase> targets; if (init is BuiltinMethodDescriptor) { targets = ((BuiltinMethodDescriptor)init).Template.Targets; } else { targets = ((BuiltinFunction)init).Targets; } PythonBinder binder = context.LanguageContext.Binder; DynamicMetaObject initInvoke = binder.CallMethod( new PythonOverloadResolver( binder, target, args, _signature, codeContext.Expression ), targets, BindingRestrictions.Empty ); res = initInvoke.Expression; initRestrictions = initInvoke.Restrictions; } else { // some weird descriptor has been put in place for __init__, we need // to call __get__ on it each time. res = MakeDynamicInitInvoke( context, args, Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.GetInitSlotMember)), codeContext.Expression, Expression.Convert(AstUtils.WeakConstant(_newType), typeof(PythonType)), Expression.Convert(AstUtils.WeakConstant(init), typeof(PythonTypeSlot)), AstUtils.Convert(target.Expression, typeof(object)) ), codeContext.Expression ); } } else { // returned something that isn't a subclass of the creating type // __init__ will not be run. res = AstUtils.Empty(); } // check for __del__ PythonTypeSlot delSlot; if (instType.TryResolveSlot(context, "__del__", out delSlot)) { res = Expression.Block( res, Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.InitializeForFinalization)), codeContext.Expression, AstUtils.Convert(target.Expression, typeof(object)) ) ); } return(BindingHelpers.AddDynamicTestAndDefer( this, new DynamicMetaObject( Expression.Block( res, target.Expression ), target.Restrict(target.LimitType).Restrictions.Merge(initRestrictions) ), args, valInfo )); }
public override DynamicMetaObject /*!*/ BindInvokeMember(InvokeMemberBinder /*!*/ action, DynamicMetaObject /*!*/[] /*!*/ args) { return(BindingHelpers.GenericInvokeMember(action, null, this, args)); }
public void HandleError([NotNull] Exception exception) { if (exception == null) { throw new ArgumentNullException("exception"); } GameLog.Server.General.Error(BuildErrorMessage(exception)); string header; string message; var gameDataException = exception as GameDataException; if (gameDataException != null) { header = _resourceManager.GetString("GAME_DATA_ERROR_HEADER"); message = _resourceManager.GetStringFormat( "GAME_DATA_ERROR_MESSAGE_FORMAT", gameDataException.Message, gameDataException.FileName); } else { header = _resourceManager.GetString("GENERIC_ERROR_HEADER"); message = _resourceManager.GetStringFormat( "GENERIC_ERROR_MESSAGE_FORMAT", exception.Message); } _dispatcherService.Invoke( (Action) (() => { var formattedTextConverter = new FormattedTextConverter(); var messageText = new TextBlock { TextWrapping = TextWrapping.Wrap }; BindingHelpers.SetInlines( messageText, (Inline[])formattedTextConverter.Convert(message)); MessageDialog.Show( header, messageText, MessageDialogButtons.Ok); var supremacyException = exception as SupremacyException; if (supremacyException == null) { ClientCommands.Exit.Execute(false); return; } switch (supremacyException.Action) { case SupremacyExceptionAction.Continue: break; case SupremacyExceptionAction.Exit: ClientCommands.Exit.Execute(false); break; default: case SupremacyExceptionAction.Undefined: case SupremacyExceptionAction.Disconnect: ClientCommands.EndGame.Execute(false); break; } })); }
/// <summary> /// Resolves path binding and prepares the inner custom binding with resolved path value. /// </summary> /// <param name="serviceProvider">Service provider given by the framework.</param> /// <returns>True if successfully prepared path binding, false if cannot resolve its value.</returns> private bool ResolveBoundPathBinding(IServiceProvider serviceProvider = null) { if (PathValueBinding == null) { return(false); } // If source is not already resolved: if (boundPathSource == null) { // Try to get the source of value for the path value binding using base mechanisms: boundPathSource = serviceProvider != null?BindingHelpers.GetBindingSource(PathValueBinding, serviceProvider, out bool source_is_resolved, out bool source_is_datacontext) : BindingHelpers.GetBindingSource(PathValueBinding, TargetObject, out source_is_resolved, out source_is_datacontext); if (!source_is_resolved || boundPathSource == null) { return(false); } // If source is datacontext then track it for future changes: if (source_is_datacontext) { (TargetObject as FrameworkElement).DataContextChanged += TargetObject_DataContextChanged; } } // Try to resolve path binding value on the source: var value = BindingHelpers.ResolvePathValue(boundPathSource, PathValueBinding.Path); // If not given a proper property path format: if (!(value is string) && !(value is PropertyPath)) { StopTrackingPathBindingUpdates(); // as we did not resolved binding, stop tracking changes on current bind if any. return(false); } // Update bound path binding by getting a copy of the precedent value: if (!providing_value) { boundPathBinding = boundPathBinding?.Clone(); if (boundPathBinding == null) { return(false); } } // Build new inner binding path based on resolved value + OverridePath property: if (value is string as_string) { if (!OverridePath && Path != null) { boundPathBinding.Path = new PropertyPath(Path.Path + "." + as_string); // TODO: path parameters? } else { boundPathBinding.Path = new PropertyPath(as_string); } } else if (value is PropertyPath asPropertyPath) { if (!OverridePath && Path != null) { boundPathBinding.Path = new PropertyPath(Path.Path + "." + asPropertyPath.Path, asPropertyPath.PathParameters); } else { boundPathBinding.Path = asPropertyPath; } } // As we resolved binding, track any further changes: StartTrackingPathBindingUpdates(); return(true); }