<commit_before>﻿using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;

namespace Discord.Commands
{
    [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
    public class Module
    {
        public TypeInfo Source { get; }
        public CommandService Service { get; }
        public string Name { get; }
        public string Prefix { get; }
        public string Summary { get; }
        public string Description { get; }
        public IEnumerable<Command> Commands { get; }
        internal object Instance { get; }

        public IReadOnlyList<PreconditionAttribute> Preconditions { get; }

        internal Module(TypeInfo source, CommandService service, object instance, ModuleAttribute moduleAttr, IDependencyMap dependencyMap)
        {
            Source = source;
            Service = service;
            Name = source.Name;
            Prefix = moduleAttr.Prefix ?? "";
            Instance = instance;

            var nameAttr = source.GetCustomAttribute<NameAttribute>();
            if (nameAttr != null)
                Name = nameAttr.Text;

            var summaryAttr = source.GetCustomAttribute<SummaryAttribute>();
            if (summaryAttr != null)
                Summary = summaryAttr.Text;

            var descriptionAttr = source.GetCustomAttribute<DescriptionAttribute>();
            if (descriptionAttr != null)
                Description = descriptionAttr.Text;

            List<Command> commands = new List<Command>();
            SearchClass(source, instance, commands, Prefix, dependencyMap);
            Commands = commands;

            Preconditions = BuildPreconditions();
        }

        private void SearchClass(TypeInfo parentType, object instance, List<Command> commands, string groupPrefix, IDependencyMap dependencyMap)
        {
            foreach (var method in parentType.DeclaredMethods)
            {
                var cmdAttr = method.GetCustomAttribute<CommandAttribute>();
                if (cmdAttr != null)
                    commands.Add(new Command(method, this, instance, cmdAttr, groupPrefix));
            }
            foreach (var type in parentType.DeclaredNestedTypes)
            {
                var groupAttrib = type.GetCustomAttribute<GroupAttribute>();
                if (groupAttrib != null)
                {
                    string nextGroupPrefix;
                    if (groupAttrib.Prefix != null)
                    {
                        if (groupPrefix != "")
                            groupPrefix += " ";
                        nextGroupPrefix = groupPrefix + groupAttrib.Prefix ?? type.Name;
                    }
                    else
                    {
                        nextGroupPrefix = groupPrefix;
                    }
                    SearchClass(type, ReflectionUtils.CreateObject(type, Service, dependencyMap), commands, nextGroupPrefix, dependencyMap);
                }
            }
        }

        private IReadOnlyList<PreconditionAttribute> BuildPreconditions()
        {
            return Source.GetCustomAttributes<PreconditionAttribute>().ToImmutableArray();
        }

        public override string ToString() => Name;
        private string DebuggerDisplay => Name;
    }
}<commit_msg>Don't add multiple spaces for multiple groups<commit_after>﻿using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;

namespace Discord.Commands
{
    [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
    public class Module
    {
        public TypeInfo Source { get; }
        public CommandService Service { get; }
        public string Name { get; }
        public string Prefix { get; }
        public string Summary { get; }
        public string Description { get; }
        public IEnumerable<Command> Commands { get; }
        internal object Instance { get; }

        public IReadOnlyList<PreconditionAttribute> Preconditions { get; }

        internal Module(TypeInfo source, CommandService service, object instance, ModuleAttribute moduleAttr, IDependencyMap dependencyMap)
        {
            Source = source;
            Service = service;
            Name = source.Name;
            Prefix = moduleAttr.Prefix ?? "";
            Instance = instance;

            var nameAttr = source.GetCustomAttribute<NameAttribute>();
            if (nameAttr != null)
                Name = nameAttr.Text;

            var summaryAttr = source.GetCustomAttribute<SummaryAttribute>();
            if (summaryAttr != null)
                Summary = summaryAttr.Text;

            var descriptionAttr = source.GetCustomAttribute<DescriptionAttribute>();
            if (descriptionAttr != null)
                Description = descriptionAttr.Text;

            List<Command> commands = new List<Command>();
            SearchClass(source, instance, commands, Prefix, dependencyMap);
            Commands = commands;

            Preconditions = BuildPreconditions();
        }

        private void SearchClass(TypeInfo parentType, object instance, List<Command> commands, string groupPrefix, IDependencyMap dependencyMap)
        {
            foreach (var method in parentType.DeclaredMethods)
            {
                var cmdAttr = method.GetCustomAttribute<CommandAttribute>();
                if (cmdAttr != null)
                    commands.Add(new Command(method, this, instance, cmdAttr, groupPrefix));
            }
            foreach (var type in parentType.DeclaredNestedTypes)
            {
                var groupAttrib = type.GetCustomAttribute<GroupAttribute>();
                if (groupAttrib != null)
                {
                    string nextGroupPrefix;
                    if (groupAttrib.Prefix != null)
                    {
                        if (groupPrefix != "")
                            nextGroupPrefix = groupPrefix + " " + groupAttrib.Prefix ?? type.Name;
                        else
                            nextGroupPrefix = groupAttrib.Prefix ?? type.Name;
                    }
                    else
                    {
                        nextGroupPrefix = groupPrefix;
                    }
                    SearchClass(type, ReflectionUtils.CreateObject(type, Service, dependencyMap), commands, nextGroupPrefix, dependencyMap);
                }
            }
        }

        private IReadOnlyList<PreconditionAttribute> BuildPreconditions()
        {
            return Source.GetCustomAttributes<PreconditionAttribute>().ToImmutableArray();
        }

        public override string ToString() => Name;
        private string DebuggerDisplay => Name;
    }
}
{'fraction_non_alphanumeric': 0.08019713261648745, 'fraction_numerical': 0.0, 'mean_word_length': 1.8425297113752122, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3499363', 'n_tokens_mistral': 1504, 'n_tokens_neox': 1458, 'n_words': 377}