public CommandTree(CommandTree?parent, CommandInfo command) { Parent = parent; Command = command; Mapped = new List <MappedCommandParameter>(); Unmapped = new List <CommandParameter>(); }
internal static ParseException UnknownCommand(CommandModel model, CommandTree?node, IEnumerable <string> args, CommandTreeToken token) { var suggestion = CommandSuggestor.Suggest(model, node?.Command, token.Value); var text = suggestion != null ? $"Did you mean '{suggestion.Name}'?" : "No such command."; return(ParseExceptionFactory.Create(args, token, $"Unknown command '{token.Value}'.", text)); }
private CommandTree ParseCommandParameters( CommandTreeParserContext context, CommandInfo command, CommandTree?parent, CommandTreeTokenStream stream) { context.ResetArgumentPosition(); var node = new CommandTree(parent, command); while (stream.Peek() != null) { var token = stream.Peek(); if (token == null) { // Should not happen, but the compiler isn't // smart enough to realize this... throw new CommandRuntimeException("Could not get the next token."); } switch (token.TokenKind) { case CommandTreeToken.Kind.LongOption: // Long option ParseOption(context, stream, token, node, true); break; case CommandTreeToken.Kind.ShortOption: // Short option ParseOption(context, stream, token, node, false); break; case CommandTreeToken.Kind.String: // Command ParseString(context, stream, node); break; case CommandTreeToken.Kind.Remaining: // Remaining stream.Consume(CommandTreeToken.Kind.Remaining); context.State = State.Remaining; break; default: throw new InvalidOperationException($"Encountered unknown token ({token.TokenKind})."); } } // Add unmapped parameters. foreach (var parameter in node.Command.Parameters) { if (node.Mapped.All(m => m.Parameter != parameter)) { node.Unmapped.Add(parameter); } } return(node); }
public static CommandValueLookup GetParameterValues(CommandTree?tree, ITypeResolver resolver) { var lookup = new CommandValueLookup(); var binder = new CommandValueBinder(lookup); CommandValidator.ValidateRequiredParameters(tree); while (tree != null) { // Process unmapped parameters. foreach (var parameter in tree.Unmapped) { if (parameter.IsFlagValue()) { // Set the flag value to an empty, not set instance. var instance = Activator.CreateInstance(parameter.ParameterType); lookup.SetValue(parameter, instance); } else { // Is this an option with a default value? if (parameter is CommandOption option && option.DefaultValue != null) { binder.Bind(parameter, resolver, option.DefaultValue?.Value); CommandValidator.ValidateParameter(parameter, lookup); } } } // Process mapped parameters. foreach (var mapped in tree.Mapped) { if (mapped.Parameter.WantRawValue) { // Just try to assign the raw value. binder.Bind(mapped.Parameter, resolver, mapped.Value); } else { var converter = GetConverter(lookup, binder, resolver, mapped.Parameter); if (converter == null) { throw RuntimeException.NoConverterFound(mapped.Parameter); } if (mapped.Parameter.IsFlagValue() && mapped.Value == null) { if (mapped.Parameter is CommandOption option && option.DefaultValue != null) { // Set the default value. binder.Bind(mapped.Parameter, resolver, option.DefaultValue?.Value); } else { // Set the flag but not the value. binder.Bind(mapped.Parameter, resolver, null); } }
public static void ValidateRequiredParameters(CommandTree?tree) { var node = tree?.GetRootCommand(); while (node != null) { foreach (var parameter in node.Unmapped) { if (parameter.Required) { switch (parameter) { case CommandArgument argument: throw CommandRuntimeException.MissingRequiredArgument(node, argument); } } } node = node.Next; } }
public static CommandSettings Bind(CommandTree?tree, Type settingsType, ITypeResolver resolver) { var lookup = CommandValueResolver.GetParameterValues(tree, resolver); // Got a constructor with at least one name corresponding to a settings? foreach (var constructor in settingsType.GetConstructors()) { var parameters = constructor.GetParameters(); if (parameters.Length > 0) { foreach (var parameter in parameters) { if (lookup.HasParameterWithName(parameter?.Name)) { // Use constructor injection. return(CommandConstructorBinder.CreateSettings(lookup, constructor, resolver)); } } } } return(CommandPropertyBinder.CreateSettings(lookup, settingsType, resolver)); }
private CommandTree ParseCommand( CommandTreeParserContext context, ICommandContainer current, CommandTree?parent, CommandTreeTokenStream stream) { // Find the command. var commandToken = stream.Consume(CommandTreeToken.Kind.String); if (commandToken == null) { throw new CommandRuntimeException("Could not consume token when parsing command."); } var command = current.FindCommand(commandToken.Value, CaseSensitivity); if (command == null) { throw CommandParseException.UnknownCommand(_configuration, parent, context.Arguments, commandToken); } return(ParseCommandParameters(context, command, parent, stream)); }
public static CommandValueLookup GetParameterValues(CommandTree?tree, ITypeResolver resolver) { var lookup = new CommandValueLookup(); var binder = new CommandValueBinder(lookup); CommandValidator.ValidateRequiredParameters(tree); while (tree != null) { // Process unmapped parameters. foreach (var parameter in tree.Unmapped) { // Got a value provider? if (parameter.ValueProvider != null) { var context = new CommandParameterContext(parameter, resolver, null); if (parameter.ValueProvider.TryGetValue(context, out var result)) { result = ConvertValue(resolver, lookup, binder, parameter, result); lookup.SetValue(parameter, result); CommandValidator.ValidateParameter(parameter, lookup, resolver); continue; } } if (parameter.IsFlagValue()) { // Set the flag value to an empty, not set instance. var instance = Activator.CreateInstance(parameter.ParameterType); lookup.SetValue(parameter, instance); } else { // Is this an option with a default value? if (parameter.DefaultValue != null) { var value = parameter.DefaultValue?.Value; value = ConvertValue(resolver, lookup, binder, parameter, value); binder.Bind(parameter, resolver, value); CommandValidator.ValidateParameter(parameter, lookup, resolver); } else if (Nullable.GetUnderlyingType(parameter.ParameterType) != null || !parameter.ParameterType.IsValueType) { lookup.SetValue(parameter, null); } } } // Process mapped parameters. foreach (var mapped in tree.Mapped) { if (mapped.Parameter.WantRawValue) { // Just try to assign the raw value. binder.Bind(mapped.Parameter, resolver, mapped.Value); } else { if (mapped.Parameter.IsFlagValue() && mapped.Value == null) { if (mapped.Parameter is CommandOption option && option.DefaultValue != null) { // Set the default value. binder.Bind(mapped.Parameter, resolver, option.DefaultValue?.Value); } else { // Set the flag but not the value. binder.Bind(mapped.Parameter, resolver, null); } }
public CommandTreeParserResult(CommandTree?tree, IRemainingArguments remaining) { Tree = tree; Remaining = remaining; }