Beispiel #1
0
        /// <summary>
        /// Try to fit the given arguments to the underlying function.
        /// This function will throw an exception if the parameters can't be applied.
        /// The parameters that are extracted from the arguments will be returned if they can be applied successfully.
        /// </summary>
        /// <param name="info">The current call <see cref="ExecutionInformation"/>.</param>
        /// <param name="arguments">The arguments that are applied to this function.</param>
        /// <param name="returnTypes">The possible return types.</param>
        /// <param name="takenArguments">How many arguments could be set.</param>
        private object[] FitArguments(ExecutionInformation info, IReadOnlyList <ICommand> arguments, IReadOnlyList <Type> returnTypes, out int takenArguments)
        {
            var parameters = new object[CommandParameter.Length];
            var filterLazy = info.GetFilterLazy();

            // takenArguments: Index through arguments which have been moved into a parameter
            // p: Iterate through parameters
            takenArguments = 0;
            for (int p = 0; p < parameters.Length; p++)
            {
                var arg = CommandParameter[p].Type;
                switch (CommandParameter[p].Kind)
                {
                case ParamKind.SpecialArguments:
                    parameters[p] = arguments;
                    break;

                case ParamKind.SpecialReturns:
                    parameters[p] = returnTypes;
                    break;

                case ParamKind.Dependency:
                    if (info.TryGet(arg, out var obj))
                    {
                        parameters[p] = obj;
                    }
                    else if (CommandParameter[p].Optional)
                    {
                        parameters[p] = null;
                    }
                    else
                    {
                        throw new MissingContextCommandException($"Command '{internCommand.Name}' missing execution context '{arg.Name}'", arg);
                    }
                    break;

                case ParamKind.NormalCommand:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }
                    parameters[p] = arguments[takenArguments];
                    takenArguments++;
                    break;

                case ParamKind.NormalParam:
                case ParamKind.NormalTailString:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }

                    var types = GetTypes(arg);
                    if (CommandParameter[p].Kind == ParamKind.NormalTailString)
                    {
                        types.Insert(0, typeof(TailString));
                    }

                    var argResultP = arguments[takenArguments].Execute(info, Array.Empty <ICommand>(), types);
                    if (CommandParameter[p].Kind == ParamKind.NormalTailString && argResultP is TailString tailString)
                    {
                        parameters[p] = tailString.Tail;
                    }
                    else
                    {
                        parameters[p] = ConvertParam(UnwrapPrimitive(argResultP), arg, filterLazy);
                    }

                    takenArguments++;
                    break;

                case ParamKind.NormalArray:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }

                    var typeArr = arg.GetElementType();
                    var args    = Array.CreateInstance(typeArr, arguments.Count - takenArguments);
                    for (int i = 0; i < args.Length; i++, takenArguments++)
                    {
                        var argResultA = arguments[takenArguments].Execute(info, Array.Empty <ICommand>(), GetTypes(typeArr));
                        var convResult = ConvertParam(UnwrapPrimitive(argResultA), typeArr, filterLazy);
                        args.SetValue(convResult, i);
                    }

                    parameters[p] = args;
                    break;

                default:
                    throw Tools.UnhandledDefault(CommandParameter[p].Kind);
                }
            }

            // Check if we were able to set enough arguments
            int wantArgumentCount = Math.Min(parameters.Length, RequiredParameters);

            if (takenArguments < wantArgumentCount && !returnTypes.Contains(typeof(ICommand)))
            {
                throw ThrowAtLeastNArguments(wantArgumentCount);
            }

            return(parameters);
        }
Beispiel #2
0
        /// <summary>
        /// Try to fit the given arguments to the underlying function.
        /// This function will throw an exception if the parameters can't be applied.
        /// The parameters that are extracted from the arguments will be returned if they can be applied successfully.
        /// </summary>
        /// <param name="info">The current call <see cref="ExecutionInformation"/>.</param>
        /// <param name="arguments">The arguments that are applied to this function.</param>
        /// <param name="returnTypes">The possible return types.</param>
        /// <param name="takenArguments">How many arguments could be set.</param>
        private object[] FitArguments(ExecutionInformation info, IReadOnlyList <ICommand> arguments, IReadOnlyList <CommandResultType> returnTypes, out int takenArguments)
        {
            var parameters = new object[CommandParameter.Length];
            var filterLazy = new Lazy <Algorithm.Filter>(() => info.TryGet <Algorithm.Filter>(out var filter) ? filter : Algorithm.Filter.DefaultFilter, false);

            // takenArguments: Index through arguments which have been moved into a parameter
            // p: Iterate through parameters
            takenArguments = 0;
            for (int p = 0; p < parameters.Length; p++)
            {
                var arg = CommandParameter[p].type;
                switch (CommandParameter[p].kind)
                {
                case ParamKind.SpecialArguments:
                    parameters[p] = arguments;
                    break;

                case ParamKind.SpecialReturns:
                    parameters[p] = returnTypes;
                    break;

                case ParamKind.Dependency:
                    if (info.TryGet(arg, out var obj))
                    {
                        parameters[p] = obj;
                    }
                    else if (CommandParameter[p].optional)
                    {
                        parameters[p] = null;
                    }
                    else
                    {
                        throw new MissingContextCommandException($"Command '{internCommand.Name}' missing execution context '{arg.Name}'", arg);
                    }
                    break;

                case ParamKind.NormalCommand:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }
                    parameters[p] = arguments[takenArguments];
                    takenArguments++;
                    break;

                case ParamKind.NormalParam:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }

                    var argResultP = ((StringCommandResult)arguments[takenArguments].Execute(info, Array.Empty <ICommand>(), XCommandSystem.ReturnString)).Content;
                    parameters[p] = ConvertParam(argResultP, arg, filterLazy.Value.Current);

                    takenArguments++;
                    break;

                case ParamKind.NormalArray:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }

                    var typeArr = arg.GetElementType();
                    var args    = Array.CreateInstance(typeArr, arguments.Count - takenArguments);
                    for (int i = 0; i < args.Length; i++, takenArguments++)
                    {
                        var argResultA = ((StringCommandResult)arguments[takenArguments].Execute(info, Array.Empty <ICommand>(), XCommandSystem.ReturnString)).Content;
                        var convResult = ConvertParam(argResultA, typeArr, filterLazy.Value.Current);
                        args.SetValue(convResult, i);
                    }

                    parameters[p] = args;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            // Check if we were able to set enough arguments
            int wantArgumentCount = Math.Min(parameters.Length, RequiredParameters);

            if (takenArguments < wantArgumentCount && !returnTypes.Contains(CommandResultType.Command))
            {
                throw ThrowAtLeastNArguments(wantArgumentCount);
            }

            return(parameters);
        }
        /// <summary>
        /// Try to fit the given arguments to the underlying function.
        /// This function will throw an exception if the parameters can't be applied.
        /// The parameters that are extracted from the arguments will be returned if they can be applied successfully.
        /// </summary>
        /// <param name="info">The current call <see cref="ExecutionInformation"/>.</param>
        /// <param name="arguments">The arguments that are applied to this function.</param>
        /// <param name="returnTypes">The possible return types.</param>
        /// <param name="takenArguments">How many arguments could be set.</param>
        public R <object[], CommandException> FitArguments(ExecutionInformation info, IReadOnlyList <ICommand> arguments, IReadOnlyList <CommandResultType> returnTypes, out int takenArguments)
        {
            var parameters = new object[CommandParameter.Length];
            var filterLazy = new Lazy <Algorithm.Filter>(() => info.TryGet <Algorithm.Filter>(out var filter) ? filter : Algorithm.Filter.DefaultFilter, false);

            // takenArguments: Index through arguments which have been moved into a parameter
            // p: Iterate through parameters
            takenArguments = 0;
            for (int p = 0; p < parameters.Length; p++)
            {
                var arg = CommandParameter[p].type;
                switch (CommandParameter[p].kind)
                {
                case ParamKind.SpecialArguments:
                    parameters[p] = arguments;
                    break;

                case ParamKind.SpecialReturns:
                    parameters[p] = returnTypes;
                    break;

                case ParamKind.Dependency:
                    if (info.TryGet(arg, out var obj))
                    {
                        parameters[p] = obj;
                    }
                    else if (CommandParameter[p].optional)
                    {
                        parameters[p] = null;
                    }
                    else
                    {
                        return(new CommandException($"Command '{internCommand.Name}' missing execution context '{arg.Name}'", CommandExceptionReason.MissingContext));
                    }
                    break;

                case ParamKind.NormalCommand:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }
                    parameters[p] = arguments[takenArguments];
                    takenArguments++;
                    break;

                case ParamKind.NormalParam:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }

                    var argResultP = ((StringCommandResult)arguments[takenArguments].Execute(info, Array.Empty <ICommand>(), XCommandSystem.ReturnString)).Content;
                    try { parameters[p] = ConvertParam(argResultP, arg, filterLazy.Value.Current); }
                    catch (FormatException ex) { return(new CommandException("Could not convert to " + UnwrapParamType(arg).Name, ex, CommandExceptionReason.CommandError)); }
                    catch (OverflowException ex) { return(new CommandException("The number is too big.", ex, CommandExceptionReason.CommandError)); }

                    takenArguments++;
                    break;

                case ParamKind.NormalArray:
                    if (takenArguments >= arguments.Count)
                    {
                        parameters[p] = GetDefault(arg); break;
                    }

                    var typeArr = arg.GetElementType();
                    var args    = Array.CreateInstance(typeArr, arguments.Count - takenArguments);
                    try
                    {
                        for (int i = 0; i < args.Length; i++, takenArguments++)
                        {
                            var argResultA = ((StringCommandResult)arguments[takenArguments].Execute(info, Array.Empty <ICommand>(), XCommandSystem.ReturnString)).Content;
                            var convResult = ConvertParam(argResultA, typeArr, filterLazy.Value.Current);
                            args.SetValue(convResult, i);
                        }
                    }
                    catch (FormatException ex) { return(new CommandException("Could not convert to " + arg.Name, ex, CommandExceptionReason.CommandError)); }
                    catch (OverflowException ex) { return(new CommandException("The number is too big.", ex, CommandExceptionReason.CommandError)); }

                    parameters[p] = args;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            // Check if we were able to set enough arguments
            if (takenArguments < Math.Min(parameters.Length, RequiredParameters) && !returnTypes.Contains(CommandResultType.Command))
            {
                return(new CommandException("Not enough arguments for function " + internCommand.Name, CommandExceptionReason.MissingParameter));
            }

            return(parameters);
        }