/// <summary> /// Resolves <see cref="CommandSchema"/>. /// </summary> public static CommandSchema Resolve(Type type, IReadOnlyList <Type>?modeTypes) { if (!KnownTypesHelpers.IsCommandType(type)) { throw CommandResolverExceptions.InvalidCommandType(type); } CommandAttribute attribute = type.GetCustomAttribute <CommandAttribute>() !; if (modeTypes != null) { if (attribute.SupportedModes != null && attribute.SupportedModes.Except(modeTypes).Any()) { throw CommandResolverExceptions.InvalidSupportedModesInCommand(type, attribute); } if (attribute.ExcludedModes != null && attribute.ExcludedModes.Except(modeTypes).Any()) { throw CommandResolverExceptions.InvalidExcludedModesInCommand(type, attribute); } } string?name = attribute.Name; CommandOptionSchema[] builtInOptions = string.IsNullOrWhiteSpace(name) ? new[] { CommandOptionSchema.HelpOption, CommandOptionSchema.VersionOption } : new[] { CommandOptionSchema.HelpOption }; CommandParameterSchema?[] parameters = type.GetProperties() .Select(CommandParameterSchemaResolver.TryResolve) .Where(p => p != null) .OrderBy(p => p !.Order) .ToArray(); CommandOptionSchema?[] options = type.GetProperties() .Select(CommandOptionSchemaResolver.TryResolve) .Where(o => o != null) .Concat(builtInOptions) .ToArray(); CommandSchema command = new CommandSchema( type, name, attribute.Description, attribute.Manual, attribute.SupportedModes, attribute.ExcludedModes, parameters !, options ! ); ValidateParameters(command); ValidateOptions(command); return(command); }
private void ResolveCommands(IReadOnlyList <Type> commandTypes) { CommandSchema?defaultCommand = null; var commands = new Dictionary <string, CommandSchema>(); var invalidCommands = new List <CommandSchema>(); foreach (Type commandType in commandTypes) { CommandSchema command = CommandSchemaResolver.Resolve(commandType, _modeTypes); if (command.IsDefault) { defaultCommand = defaultCommand is null ? command : throw CommandResolverExceptions.TooManyDefaultCommands(); } else if (!commands.TryAdd(command.Name !, command)) { invalidCommands.Add(command); } } if (commands.Count == 0 && defaultCommand is null) { throw CommandResolverExceptions.NoCommandsDefined(); } if (invalidCommands.Count > 0) { IGrouping <string, CommandSchema> duplicateNameGroup = invalidCommands.Union(commands.Values) .GroupBy(c => c.Name !, StringComparer.Ordinal) .First(); throw CommandResolverExceptions.CommandsWithSameName(duplicateNameGroup.Key, duplicateNameGroup.ToArray()); } DefaultCommand = defaultCommand; Commands = commands; }