Exemplo n.º 1
0
        private static void BuildOptionParameter(
            ReplBuilder builder,
            ReplCommandBuilder commandBuilder,
            ParameterInfo parameter,
            ReplOptionAttribute replOption,
            ReplCommandOptionParameterBuilder paramBuilder)
        {
            if (replOption.TypeName == null)
            {
                throw new ArgumentNullException(nameof(replOption.TypeName));
            }

            paramBuilder
            .WithTypeName(replOption.TypeName)
            .WithCaption(replOption.Caption)
            .WithValueCount(replOption.ValueCount)
            .WithDescription(replOption.Caption);

            if (!parameter.HasDefaultValue)
            {
                paramBuilder.WithIsRequired();
            }

            if (parameter.ParameterType.IsGenericType &&
                parameter.ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable <string>).GetGenericTypeDefinition())
            {
                paramBuilder.WithIsRepeated();
            }

            foreach (var replExample in parameter.GetCustomAttributes <ReplExampleAttribute>())
            {
                paramBuilder.WithExample(replExample.Command, exampleBuilder =>
                {
                    exampleBuilder
                    .WithCaption(exampleBuilder.caption)
                    .WithDescription(exampleBuilder.description);
                });

                if (replExample.Scope >= ReplExampleScope.Parent)
                {
                    commandBuilder.WithExample(replExample.Command, exampleBuilder =>
                    {
                        exampleBuilder
                        .WithCaption(exampleBuilder.caption)
                        .WithDescription(exampleBuilder.description);
                    });
                }

                if (replExample.Scope >= ReplExampleScope.All)
                {
                    builder.WithExample(replExample.Command, exampleBuilder =>
                    {
                        exampleBuilder
                        .WithCaption(exampleBuilder.caption)
                        .WithDescription(exampleBuilder.description);
                    });
                }
            }
        }
Exemplo n.º 2
0
        public ReplBuilder WithCommand(string name, Action <ReplCommandBuilder> configCommand)
        {
            var commandBuilder = new ReplCommandBuilder().WithName(name);

            configCommand.Invoke(commandBuilder);
            commands.Add(commandBuilder);
            return(this);
        }
Exemplo n.º 3
0
 public ReplCommandRuntime(ReplCommandBuilder builder)
 {
     this.Names       = new ReadOnlyCollection <string>(builder.Names.ToArray());
     this.Category    = builder.Category;
     this.Caption     = builder.Caption;
     this.Description = builder.description;
     // TODO: Check parameter ambiguities, only last positional can be repeated, required must be in order: true, true, false, false
     this.Parameters           = new ReadOnlyCollection <ReplParameterRuntime>(builder.Parameters.Select(e => new ReplParameterRuntime(e)).ToArray());
     this.Examples             = new ReadOnlyCollection <ReplExampleRuntime>(builder.examples.Select(e => new ReplExampleRuntime(e)).ToArray());
     this.PositionalParameters = new ReadOnlyCollection <ReplParameterRuntime>(this.Parameters.Where(p => p.ParameterType == ReplParameterType.Positional).ToArray());
     if (builder.Execute == null)
     {
         throw new ArgumentNullException(nameof(builder.Execute));
     }
     this.Execute = builder.Execute;
 }
Exemplo n.º 4
0
        private static void BuildFlagParameter(
            ReplBuilder builder,
            ReplCommandBuilder commandBuilder,
            ParameterInfo parameter,
            ReplFlagAttribute replFlag,
            ReplCommandFlagParameterBuilder paramBuilder)
        {
            if (parameter.ParameterType != typeof(bool))
            {
                ConsoleEx.WriteLine(ConsoleColor.Red, $"Flag `{commandBuilder.Names.First()} {AsOptionName(parameter.Name)}` cannot have a type other than `bool`, but found with type `{parameter.ParameterType.Name}`");
            }

            paramBuilder
            .WithCaption(replFlag.Caption)
            .WithDescription(replFlag.Caption);

            foreach (var replExample in parameter.GetCustomAttributes <ReplExampleAttribute>())
            {
                paramBuilder.WithExample(replExample.Command, exampleBuilder =>
                {
                    exampleBuilder
                    .WithCaption(exampleBuilder.caption)
                    .WithDescription(exampleBuilder.description);
                });

                if (replExample.Scope >= ReplExampleScope.Parent)
                {
                    commandBuilder.WithExample(replExample.Command, exampleBuilder =>
                    {
                        exampleBuilder
                        .WithCaption(exampleBuilder.caption)
                        .WithDescription(exampleBuilder.description);
                    });
                }

                if (replExample.Scope >= ReplExampleScope.All)
                {
                    builder.WithExample(replExample.Command, exampleBuilder =>
                    {
                        exampleBuilder
                        .WithCaption(exampleBuilder.caption)
                        .WithDescription(exampleBuilder.description);
                    });
                }
            }
        }
Exemplo n.º 5
0
        private static void BuildCommand(
            IServiceProvider serviceProvider,
            IReplBase replInstance,
            ReplBuilder builder,
            MethodInfo method,
            ReplCommandAttribute command,
            ReplCommandBuilder commandBuilder)
        {
            commandBuilder
            .WithCaption(command.Caption)
            .WithDescription(command.Description);

            foreach (var namesAttr in method.GetCustomAttributes <ReplNamesAttribute>())
            {
                foreach (var name in namesAttr.Names)
                {
                    commandBuilder.WithName(name);
                }
            }

            foreach (var replExample in method.GetCustomAttributes <ReplExampleAttribute>())
            {
                commandBuilder.WithExample(replExample.Command, exampleBuilder =>
                {
                    exampleBuilder
                    .WithCaption(exampleBuilder.caption)
                    .WithDescription(exampleBuilder.description);
                });

                if (replExample.Scope >= ReplExampleScope.Parent)
                {
                    builder.WithExample(replExample.Command, exampleBuilder =>
                    {
                        exampleBuilder
                        .WithCaption(exampleBuilder.caption)
                        .WithDescription(exampleBuilder.description);
                    });
                }
            }

            var parameters = method.GetParameters();

            foreach (var parameter in parameters)
            {
                var replParam           = parameter.GetCustomAttribute <ReplParamAttribute>();
                var replOption          = parameter.GetCustomAttribute <ReplOptionAttribute>();
                var replFlag            = parameter.GetCustomAttribute <ReplFlagAttribute>();
                var fromServiceProvider = parameter.GetCustomAttribute <ReplServiceAttribute>() != null;

                if (replParam != null)
                {
                    commandBuilder.WithPositional(parameter.Name, paramBuilder =>
                    {
                        BuildPositionalParameter(builder, commandBuilder, parameter, replParam, paramBuilder);
                    });
                }
                else if (replOption != null)
                {
                    commandBuilder.WithOption(parameter.Name, paramBuilder =>
                    {
                        BuildOptionParameter(builder, commandBuilder, parameter, replOption, paramBuilder);
                    });
                }
                else if (replFlag != null)
                {
                    commandBuilder.WithFlag(parameter.Name, paramBuilder =>
                    {
                        BuildFlagParameter(builder, commandBuilder, parameter, replFlag, paramBuilder);
                    });
                }
                else
                {
                    if (!parameter.HasDefaultValue &&
                        !fromServiceProvider &&
                        parameter.ParameterType != typeof(CancellationToken) &&
                        parameter.ParameterType != typeof(Dictionary <string, object>))
                    {
                        string message = $"Parameter {parameter.Name} from command {method.Name} cannot be fulfilled";
                        ConsoleEx.WriteLine(ConsoleColor.Red, message);
                        throw new InvalidOperationException(message);
                    }
                }
            }

            Task ExecuteAsync(Dictionary <string, object> values, CancellationToken cancellationToken)
            {
                var paramValues = new object[parameters.Length];

                // TODO: Optimize
                for (int i = 0; i < parameters.Length; i++)
                {
                    if (values.TryGetValue(parameters[i].Name, out var value))
                    {
                        // TODO: Bind depending on the param type
                        paramValues[i] = value;
                    }
                    else if (parameters[i].GetCustomAttribute <ReplServiceAttribute>() != null)
                    {
                        if (parameters[i].HasDefaultValue)
                        {
                            paramValues[i] = serviceProvider.GetService(parameters[i].ParameterType);
                        }
                        else
                        {
                            paramValues[i] = serviceProvider.GetRequiredService(parameters[i].ParameterType);
                        }
                    }
                    else if (parameters[i].ParameterType == typeof(CancellationToken))
                    {
                        paramValues[i] = cancellationToken;
                    }
                    else if (parameters[i].ParameterType == typeof(Dictionary <string, object>))
                    {
                        paramValues[i] = values;
                    }
                    else if (parameters[i].HasDefaultValue)
                    {
                        paramValues[i] = parameters[i].DefaultValue;
                    }
                    else
                    {
                        string message = $"Parameter {parameters[i].Name} from command {method.Name} cannot be bound";
                        ConsoleEx.WriteLine(ConsoleColor.Red, message);
                        throw new InvalidOperationException(message);
                    }
                }

                var result = method.Invoke(replInstance, paramValues);

                // TODO: Catch exceptions here or in the engine?

                if (result is Task task && typeof(Task).IsAssignableFrom(method.ReturnType))
                {
                    return(task);
                }

                return(Task.CompletedTask);
            }

            commandBuilder.WithExecute(ExecuteAsync);
        }