From 94d6acc00e0e1aada0c786b68b88693be4fd46d8 Mon Sep 17 00:00:00 2001 From: RogueException Date: Fri, 12 Aug 2016 06:36:06 -0300 Subject: [PATCH] Exposed reflection classes on commands, modules and parameters --- src/Discord.Net.Commands/Command.cs | 18 +++++++------ src/Discord.Net.Commands/CommandParameter.cs | 9 ++++--- src/Discord.Net.Commands/CommandParser.cs | 4 +-- src/Discord.Net.Commands/CommandService.cs | 2 +- src/Discord.Net.Commands/Module.cs | 28 +++++++++++--------- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs index c088277f2..b0dd4733c 100644 --- a/src/Discord.Net.Commands/Command.cs +++ b/src/Discord.Net.Commands/Command.cs @@ -13,6 +13,7 @@ namespace Discord.Commands private readonly object _instance; private readonly Func, Task> _action; + public MethodInfo Source { get; } public string Name { get; } public string Description { get; } public string Summary { get; } @@ -21,25 +22,26 @@ namespace Discord.Commands public IReadOnlyList Parameters { get; } public IReadOnlyList Preconditions { get; } - internal Command(Module module, object instance, CommandAttribute attribute, MethodInfo methodInfo, string groupPrefix) + internal Command(MethodInfo source, Module module, object instance, CommandAttribute attribute, string groupPrefix) { + Source = source; Module = module; _instance = instance; - Name = methodInfo.Name; + Name = source.Name; Text = groupPrefix + attribute.Text; - var description = methodInfo.GetCustomAttribute(); + var description = source.GetCustomAttribute(); if (description != null) Description = description.Text; - var summary = methodInfo.GetCustomAttribute(); + var summary = source.GetCustomAttribute(); if (summary != null) Summary = summary.Text; - Parameters = BuildParameters(methodInfo); - Preconditions = BuildPreconditions(methodInfo); - _action = BuildAction(methodInfo); + Parameters = BuildParameters(source); + Preconditions = BuildPreconditions(source); + _action = BuildAction(source); } public async Task CheckPreconditions(IMessage context) @@ -135,7 +137,7 @@ namespace Discord.Commands bool isOptional = parameter.IsOptional; object defaultValue = parameter.HasDefaultValue ? parameter.DefaultValue : null; - paramBuilder.Add(new CommandParameter(name, summary, type, reader, isOptional, isRemainder, isMultiple, defaultValue)); + paramBuilder.Add(new CommandParameter(parameters[i], name, summary, type, reader, isOptional, isRemainder, isMultiple, defaultValue)); } return paramBuilder.ToImmutable(); } diff --git a/src/Discord.Net.Commands/CommandParameter.cs b/src/Discord.Net.Commands/CommandParameter.cs index f0b6f16b3..860ab8190 100644 --- a/src/Discord.Net.Commands/CommandParameter.cs +++ b/src/Discord.Net.Commands/CommandParameter.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Reflection; using System.Threading.Tasks; namespace Discord.Commands @@ -9,19 +10,21 @@ namespace Discord.Commands { private readonly TypeReader _reader; + public ParameterInfo Source { get; } public string Name { get; } public string Summary { get; } public bool IsOptional { get; } public bool IsRemainder { get; } public bool IsMultiple { get; } - public Type Type { get; } + public Type ElementType { get; } internal object DefaultValue { get; } - public CommandParameter(string name, string summary, Type type, TypeReader reader, bool isOptional, bool isRemainder, bool isMultiple, object defaultValue) + public CommandParameter(ParameterInfo source, string name, string summary, Type type, TypeReader reader, bool isOptional, bool isRemainder, bool isMultiple, object defaultValue) { + Source = source; Name = name; Summary = summary; - Type = type; + ElementType = type; _reader = reader; IsOptional = isOptional; IsRemainder = isRemainder; diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index 0cdfaa52f..cceaa4a65 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -123,9 +123,9 @@ namespace Discord.Commands if (curPos == endPos) { - Array realParams = Array.CreateInstance(curParam.Type, paramsList.Count); + Array realParams = Array.CreateInstance(curParam.ElementType, paramsList.Count); for (int i = 0; i < paramsList.Count; i++) - realParams.SetValue(Convert.ChangeType(paramsList[i], curParam.Type), i); + realParams.SetValue(Convert.ChangeType(paramsList[i], curParam.ElementType), i); argList.Add(realParams); diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index e4453115c..7d462d610 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -120,7 +120,7 @@ namespace Discord.Commands if (_modules.ContainsKey(moduleInstance.GetType())) return _modules[moduleInstance.GetType()]; - var loadedModule = new Module(this, moduleInstance, moduleAttr, typeInfo); + var loadedModule = new Module(typeInfo, this, moduleInstance, moduleAttr); _modules[moduleInstance.GetType()] = loadedModule; foreach (var cmd in loadedModule.Commands) diff --git a/src/Discord.Net.Commands/Module.cs b/src/Discord.Net.Commands/Module.cs index 326b7af9d..f965d78ab 100644 --- a/src/Discord.Net.Commands/Module.cs +++ b/src/Discord.Net.Commands/Module.cs @@ -8,6 +8,7 @@ namespace Discord.Commands [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public class Module { + public TypeInfo Source { get; } public CommandService Service { get; } public string Name { get; } public string Summary { get; } @@ -17,38 +18,39 @@ namespace Discord.Commands public IReadOnlyList Preconditions { get; } - internal Module(CommandService service, object instance, ModuleAttribute moduleAttr, TypeInfo typeInfo) + internal Module(TypeInfo source, CommandService service, object instance, ModuleAttribute moduleAttr) { + Source = source; Service = service; - Name = typeInfo.Name; + Name = source.Name; Instance = instance; - var summaryAttr = typeInfo.GetCustomAttribute(); + var summaryAttr = source.GetCustomAttribute(); if (summaryAttr != null) Summary = summaryAttr.Text; - var descriptionAttr = typeInfo.GetCustomAttribute(); + var descriptionAttr = source.GetCustomAttribute(); if (descriptionAttr != null) Description = descriptionAttr.Text; List commands = new List(); - SearchClass(instance, commands, typeInfo, moduleAttr.Prefix ?? ""); + SearchClass(source, instance, commands, moduleAttr.Prefix ?? ""); Commands = commands; - Preconditions = BuildPreconditions(typeInfo); + Preconditions = BuildPreconditions(); } - private void SearchClass(object instance, List commands, TypeInfo typeInfo, string groupPrefix) + private void SearchClass(TypeInfo parentType, object instance, List commands, string groupPrefix) { if (groupPrefix != "") groupPrefix += " "; - foreach (var method in typeInfo.DeclaredMethods) + foreach (var method in parentType.DeclaredMethods) { var cmdAttr = method.GetCustomAttribute(); if (cmdAttr != null) - commands.Add(new Command(this, instance, cmdAttr, method, groupPrefix)); + commands.Add(new Command(method, this, instance, cmdAttr, groupPrefix)); } - foreach (var type in typeInfo.DeclaredNestedTypes) + foreach (var type in parentType.DeclaredNestedTypes) { var groupAttrib = type.GetCustomAttribute(); if (groupAttrib != null) @@ -58,14 +60,14 @@ namespace Discord.Commands nextGroupPrefix = groupPrefix + groupAttrib.Prefix ?? type.Name; else nextGroupPrefix = groupPrefix; - SearchClass(ReflectionUtils.CreateObject(type, Service), commands, type, nextGroupPrefix); + SearchClass(type, ReflectionUtils.CreateObject(type, Service), commands, nextGroupPrefix); } } } - private IReadOnlyList BuildPreconditions(TypeInfo typeInfo) + private IReadOnlyList BuildPreconditions() { - return typeInfo.GetCustomAttributes().ToImmutableArray(); + return Source.GetCustomAttributes().ToImmutableArray(); } public override string ToString() => Name;