示例#1
0
        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));
 });
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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
                       ));
        }
示例#5
0
 public override DynamicMetaObject /*!*/ BindInvokeMember(InvokeMemberBinder /*!*/ action, DynamicMetaObject /*!*/[] /*!*/ args)
 {
     return(BindingHelpers.GenericInvokeMember(action, null, this, args));
 }
示例#6
0
        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);
        }