From a04cf5201aea35239eaeee7be9bd4ca37fb6e37f Mon Sep 17 00:00:00 2001 From: RogueException Date: Sat, 30 Jul 2016 22:24:02 -0300 Subject: [PATCH] Cleaned up params implementation --- src/Discord.Net.Commands/Command.cs | 24 ++++++++------------ src/Discord.Net.Commands/CommandParameter.cs | 10 +++----- src/Discord.Net.Commands/CommandParser.cs | 18 ++++++--------- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs index 4f5489b6a..5729e4c81 100644 --- a/src/Discord.Net.Commands/Command.cs +++ b/src/Discord.Net.Commands/Command.cs @@ -71,7 +71,6 @@ namespace Discord.Commands { var parameter = parameters[i]; var type = parameter.ParameterType; - Type underlyingType = null; if (i == 0) { @@ -81,20 +80,18 @@ namespace Discord.Commands continue; } - // TODO: is there a better way of detecting 'params'? - bool isParams = type.IsArray && i == parameters.Length - 1; - if (isParams) - underlyingType = type.GetElementType(); - else - underlyingType = type; + //Detect 'params' + bool isMultiple = parameter.GetCustomAttribute() != null; + if (isMultiple) + type = type.GetElementType(); - var reader = Module.Service.GetTypeReader(underlyingType); - var underlyingTypeInfo = underlyingType.GetTypeInfo(); + var reader = Module.Service.GetTypeReader(type); var typeInfo = type.GetTypeInfo(); - if (reader == null && underlyingTypeInfo.IsEnum) + //Detect enums + if (reader == null && typeInfo.IsEnum) { - reader = EnumTypeReader.GetReader(underlyingType); + reader = EnumTypeReader.GetReader(type); Module.Service.AddTypeReader(type, reader); } @@ -110,7 +107,7 @@ namespace Discord.Commands bool isOptional = parameter.IsOptional; object defaultValue = parameter.HasDefaultValue ? parameter.DefaultValue : null; - paramBuilder.Add(new CommandParameter(name, description, type, underlyingType, reader, isOptional, isRemainder, isParams, defaultValue)); + paramBuilder.Add(new CommandParameter(name, description, type, reader, isOptional, isRemainder, isMultiple, defaultValue)); } return paramBuilder.ToImmutable(); } @@ -118,8 +115,7 @@ namespace Discord.Commands { if (methodInfo.ReturnType != typeof(Task)) throw new InvalidOperationException("Commands must return a non-generic Task."); - - //TODO: Temporary reflection hack. Lets build an actual expression tree here. + return (msg, args) => { object[] newArgs = new object[args.Count + 1]; diff --git a/src/Discord.Net.Commands/CommandParameter.cs b/src/Discord.Net.Commands/CommandParameter.cs index 2be39bbf5..f18b1a13b 100644 --- a/src/Discord.Net.Commands/CommandParameter.cs +++ b/src/Discord.Net.Commands/CommandParameter.cs @@ -1,11 +1,9 @@ using System; using System.Diagnostics; -using System.Reflection; using System.Threading.Tasks; namespace Discord.Commands { - //TODO: Add support for Multiple [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public class CommandParameter { @@ -15,21 +13,19 @@ namespace Discord.Commands public string Description { get; } public bool IsOptional { get; } public bool IsRemainder { get; } - public bool IsParams { get; } + public bool IsMultiple { get; } public Type Type { get; } - public Type UnderlyingType { get; } internal object DefaultValue { get; } - public CommandParameter(string name, string description, Type type, Type underlyingType, TypeReader reader, bool isOptional, bool isRemainder, bool isParams, object defaultValue) + public CommandParameter(string name, string description, Type type, TypeReader reader, bool isOptional, bool isRemainder, bool isMultiple, object defaultValue) { Name = name; Description = description; Type = type; - UnderlyingType = underlyingType; _reader = reader; IsOptional = isOptional; IsRemainder = isRemainder; - IsParams = isParams; + IsMultiple = isMultiple; DefaultValue = defaultValue; } diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index e9af0ce44..0cdfaa52f 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -23,8 +23,8 @@ namespace Discord.Commands int endPos = input.Length; var curPart = ParserPart.None; int lastArgEndPos = int.MinValue; - IList paramsList = null; // TODO: could we use a better type? var argList = ImmutableArray.CreateBuilder(); + List paramsList = null; // TODO: could we use a better type? bool isEscaping = false; char c; @@ -74,10 +74,6 @@ namespace Discord.Commands argBuilder.Append(c); continue; } - if (curParam != null && curParam.IsParams) - { - paramsList = new List(); - } if (c == '\"') { curPart = ParserPart.QuotedParameter; @@ -119,17 +115,17 @@ namespace Discord.Commands if (!typeReaderResult.IsSuccess) return ParseResult.FromError(typeReaderResult); - if (curParam.IsParams) + if (curParam.IsMultiple) { + if (paramsList == null) + paramsList = new List(); paramsList.Add(typeReaderResult.Value); if (curPos == endPos) { - // TODO: can this logic be improved? - object[] _params = paramsList.ToArray(); - Array realParams = Array.CreateInstance(curParam.UnderlyingType, _params.Length); - for (int i = 0; i < _params.Length; i++) - realParams.SetValue(Convert.ChangeType(_params[i], curParam.UnderlyingType), i); + Array realParams = Array.CreateInstance(curParam.Type, paramsList.Count); + for (int i = 0; i < paramsList.Count; i++) + realParams.SetValue(Convert.ChangeType(paramsList[i], curParam.Type), i); argList.Add(realParams);