Пример #1
0
        private void RegisterCommands(Type t, CommandGroupBuilder currentParent, out List <CommandBuilder> foundCommands)
        {
            var ti = t.GetTypeInfo();

            var lifespan       = ti.GetCustomAttribute <ModuleLifespanAttribute>();
            var moduleLifespan = lifespan != null ? lifespan.Lifespan : ModuleLifespan.Singleton;

            var module = new CommandModuleBuilder()
                         .WithType(t)
                         .WithLifespan(moduleLifespan)
                         .Build(this.Services);

            // restrict parent lifespan to more or equally restrictive
            if (currentParent?.Module is TransientCommandModule && moduleLifespan != ModuleLifespan.Transient)
            {
                throw new InvalidOperationException("In a transient module, child modules can only be transient.");
            }

            // check if we are anything
            var groupBuilder     = new CommandGroupBuilder(module);
            var isModule         = false;
            var moduleAttributes = ti.GetCustomAttributes();
            var moduleHidden     = false;
            var moduleChecks     = new List <CheckBaseAttribute>();

            foreach (var xa in moduleAttributes)
            {
                switch (xa)
                {
                case GroupAttribute g:
                    isModule = true;
                    var moduleName = g.Name;
                    if (moduleName == null)
                    {
                        moduleName = ti.Name;

                        if (moduleName.EndsWith("Group") && moduleName != "Group")
                        {
                            moduleName = moduleName.Substring(0, moduleName.Length - 5);
                        }
                        else if (moduleName.EndsWith("Module") && moduleName != "Module")
                        {
                            moduleName = moduleName.Substring(0, moduleName.Length - 6);
                        }
                        else if (moduleName.EndsWith("Commands") && moduleName != "Commands")
                        {
                            moduleName = moduleName.Substring(0, moduleName.Length - 8);
                        }
                    }

                    if (!this.Config.CaseSensitive)
                    {
                        moduleName = moduleName.ToLowerInvariant();
                    }

                    groupBuilder.WithName(moduleName);

                    foreach (var mi in ti.DeclaredMethods.Where(x => x.IsCommandCandidate(out _) && x.GetCustomAttribute <GroupCommandAttribute>() != null))
                    {
                        groupBuilder.WithOverload(new CommandOverloadBuilder(mi));
                    }
                    break;

                case AliasesAttribute a:
                    foreach (var xalias in a.Aliases)
                    {
                        groupBuilder.WithAlias(this.Config.CaseSensitive ? xalias : xalias.ToLowerInvariant());
                    }
                    break;

                case HiddenAttribute h:
                    groupBuilder.WithHiddenStatus(true);
                    moduleHidden = true;
                    break;

                case DescriptionAttribute d:
                    groupBuilder.WithDescription(d.Description);
                    break;

                case CheckBaseAttribute c:
                    moduleChecks.Add(c);
                    groupBuilder.WithExecutionCheck(c);
                    break;

                default:
                    groupBuilder.WithCustomAttribute(xa);
                    break;
                }
            }

            if (!isModule)
            {
                groupBuilder = null;
            }

            // candidate methods
            var methods         = ti.DeclaredMethods;
            var commands        = new List <CommandBuilder>();
            var commandBuilders = new Dictionary <string, CommandBuilder>();

            foreach (var m in methods)
            {
                if (!m.IsCommandCandidate(out _))
                {
                    continue;
                }

                var attrs = m.GetCustomAttributes();
                if (!(attrs.FirstOrDefault(xa => xa is CommandAttribute) is CommandAttribute cattr))
                {
                    continue;
                }

                var commandName = cattr.Name;
                if (commandName == null)
                {
                    commandName = m.Name;
                    if (commandName.EndsWith("Async") && commandName != "Async")
                    {
                        commandName = commandName.Substring(0, commandName.Length - 5);
                    }
                }

                if (!this.Config.CaseSensitive)
                {
                    commandName = commandName.ToLowerInvariant();
                }

                if (!commandBuilders.TryGetValue(commandName, out var commandBuilder))
                {
                    commandBuilders.Add(commandName, commandBuilder = new CommandBuilder(module).WithName(commandName));

                    if (!isModule)
                    {
                        if (currentParent != null)
                        {
                            currentParent.WithChild(commandBuilder);
                        }
                        else
                        {
                            commands.Add(commandBuilder);
                        }
                    }
                    else
                    {
                        groupBuilder.WithChild(commandBuilder);
                    }
                }

                commandBuilder.WithOverload(new CommandOverloadBuilder(m));

                if (!isModule && moduleChecks.Any())
                {
                    foreach (var chk in moduleChecks)
                    {
                        commandBuilder.WithExecutionCheck(chk);
                    }
                }

                foreach (var xa in attrs)
                {
                    switch (xa)
                    {
                    case AliasesAttribute a:
                        foreach (var xalias in a.Aliases)
                        {
                            commandBuilder.WithAlias(this.Config.CaseSensitive ? xalias : xalias.ToLowerInvariant());
                        }
                        break;

                    case CheckBaseAttribute p:
                        commandBuilder.WithExecutionCheck(p);
                        break;

                    case DescriptionAttribute d:
                        commandBuilder.WithDescription(d.Description);
                        break;

                    case HiddenAttribute h:
                        commandBuilder.WithHiddenStatus(true);
                        break;

                    default:
                        commandBuilder.WithCustomAttribute(xa);
                        break;
                    }
                }

                if (!isModule && moduleHidden)
                {
                    commandBuilder.WithHiddenStatus(true);
                }
            }

            // candidate types
            var types = ti.DeclaredNestedTypes
                        .Where(xt => xt.IsModuleCandidateType() && xt.DeclaredConstructors.Any(xc => xc.IsPublic));

            foreach (var type in types)
            {
                this.RegisterCommands(type.AsType(), groupBuilder, out var tempCommands);

                if (isModule && tempCommands != null)
                {
                    foreach (var xtcmd in tempCommands)
                    {
                        groupBuilder.WithChild(xtcmd);
                    }
                }
                else if (tempCommands != null)
                {
                    commands.AddRange(tempCommands);
                }
            }

            if (isModule && currentParent == null)
            {
                commands.Add(groupBuilder);
            }
            else if (isModule)
            {
                currentParent.WithChild(groupBuilder);
            }
            foundCommands = commands;
        }
        private void RegisterCommands(Type t, CommandGroupBuilder currentParent, out List <CommandBuilder> commands)
        {
            var ti = t.GetTypeInfo();

            var lifespan = ti.GetCustomAttribute <ModuleLifespanAttribute>();
            var module   = new CommandModuleBuilder()
                           .WithType(t)
                           .WithLifespan(lifespan != null ? lifespan.Lifespan : ModuleLifespan.Singleton)
                           .Build(this.Services);

            // check if we are anything
            var cgbldr     = new CommandGroupBuilder(module);
            var is_mdl     = false;
            var mdl_attrs  = ti.GetCustomAttributes();
            var mdl_hidden = false;
            var mdl_chks   = new List <CheckBaseAttribute>();

            foreach (var xa in mdl_attrs)
            {
                switch (xa)
                {
                case GroupAttribute g:
                    is_mdl = true;
                    var mdl_name = g.Name;
                    if (mdl_name == null)
                    {
                        mdl_name = ti.Name;

                        if (mdl_name.EndsWith("Group") && mdl_name != "Group")
                        {
                            mdl_name = mdl_name.Substring(0, mdl_name.Length - 5);
                        }
                        else if (mdl_name.EndsWith("Module") && mdl_name != "Module")
                        {
                            mdl_name = mdl_name.Substring(0, mdl_name.Length - 6);
                        }
                        else if (mdl_name.EndsWith("Commands") && mdl_name != "Commands")
                        {
                            mdl_name = mdl_name.Substring(0, mdl_name.Length - 8);
                        }
                    }

                    if (!this.Config.CaseSensitive)
                    {
                        mdl_name = mdl_name.ToLowerInvariant();
                    }

                    cgbldr.WithName(mdl_name);

                    foreach (var mi in ti.DeclaredMethods.Where(x => x.IsCommandCandidate(out _) && x.GetCustomAttribute <GroupCommandAttribute>() != null))
                    {
                        cgbldr.WithOverload(new CommandOverloadBuilder(mi));
                    }
                    break;

                case AliasesAttribute a:
                    foreach (var xalias in a.Aliases)
                    {
                        cgbldr.WithAlias(this.Config.CaseSensitive ? xalias : xalias.ToLowerInvariant());
                    }
                    break;

                case HiddenAttribute h:
                    cgbldr.WithHiddenStatus(true);
                    break;

                case DescriptionAttribute d:
                    cgbldr.WithDescription(d.Description);
                    break;

                case CheckBaseAttribute c:
                    mdl_chks.Add(c);
                    cgbldr.WithExecutionCheck(c);
                    break;

                default:
                    cgbldr.WithCustomAttribute(xa);
                    break;
                }
            }

            if (!is_mdl)
            {
                cgbldr = null;
            }

            // candidate methods
            var ms    = ti.DeclaredMethods;
            var cmds  = new List <CommandBuilder>();
            var cblds = new Dictionary <string, CommandBuilder>();

            foreach (var m in ms)
            {
                if (!m.IsCommandCandidate(out _))
                {
                    continue;
                }

                var attrs = m.GetCustomAttributes();
                var cattr = attrs.FirstOrDefault(xa => xa is CommandAttribute) as CommandAttribute;
                if (cattr == null)
                {
                    continue;
                }

                var cname = cattr.Name;
                if (cname == null)
                {
                    cname = m.Name;
                    if (cname.EndsWith("Async") && cname != "Async")
                    {
                        cname = cname.Substring(0, cname.Length - 5);
                    }
                }

                if (!this.Config.CaseSensitive)
                {
                    cname = cname.ToLowerInvariant();
                }

                if (!cblds.TryGetValue(cname, out var cmdbld))
                {
                    cblds.Add(cname, cmdbld = new CommandBuilder(module).WithName(cname));

                    if (!is_mdl)
                    {
                        if (currentParent != null)
                        {
                            currentParent.WithChild(cmdbld);
                        }
                        else
                        {
                            cmds.Add(cmdbld);
                        }
                    }
                    else
                    {
                        cgbldr.WithChild(cmdbld);
                    }
                }

                cmdbld.WithOverload(new CommandOverloadBuilder(m));

                if (!is_mdl && mdl_chks.Any())
                {
                    foreach (var chk in mdl_chks)
                    {
                        cmdbld.WithExecutionCheck(chk);
                    }
                }

                foreach (var xa in attrs)
                {
                    switch (xa)
                    {
                    case AliasesAttribute a:
                        foreach (var xalias in a.Aliases)
                        {
                            cmdbld.WithAlias(this.Config.CaseSensitive ? xalias : xalias.ToLowerInvariant());
                        }
                        break;

                    case CheckBaseAttribute p:
                        cmdbld.WithExecutionCheck(p);
                        break;

                    case DescriptionAttribute d:
                        cmdbld.WithDescription(d.Description);
                        break;

                    case HiddenAttribute h:
                        cmdbld.WithHiddenStatus(true);
                        break;

                    default:
                        cmdbld.WithCustomAttribute(xa);
                        break;
                    }
                }

                if (!is_mdl && mdl_hidden)
                {
                    cmdbld.WithHiddenStatus(true);
                }
            }

            // candidate types
            var ts = ti.DeclaredNestedTypes
                     .Where(xt => xt.IsModuleCandidateType() && xt.DeclaredConstructors.Any(xc => xc.IsPublic));

            foreach (var xt in ts)
            {
                this.RegisterCommands(xt.AsType(), cgbldr, out var tcmds);

                if (is_mdl && tcmds != null)
                {
                    foreach (var xtcmd in tcmds)
                    {
                        cgbldr.WithChild(xtcmd);
                    }
                }
                else if (tcmds != null)
                {
                    cmds.AddRange(tcmds);
                }
            }

            if (is_mdl && currentParent == null)
            {
                cmds.Add(cgbldr);
            }
            else if (is_mdl)
            {
                currentParent.WithChild(cgbldr);
            }
            commands = cmds;
        }