Cleaned up params implementation
This commit is contained in:
@@ -71,7 +71,6 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
var parameter = parameters[i];
|
var parameter = parameters[i];
|
||||||
var type = parameter.ParameterType;
|
var type = parameter.ParameterType;
|
||||||
Type underlyingType = null;
|
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
@@ -81,20 +80,18 @@ namespace Discord.Commands
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: is there a better way of detecting 'params'?
|
//Detect 'params'
|
||||||
bool isParams = type.IsArray && i == parameters.Length - 1;
|
bool isMultiple = parameter.GetCustomAttribute<ParamArrayAttribute>() != null;
|
||||||
if (isParams)
|
if (isMultiple)
|
||||||
underlyingType = type.GetElementType();
|
type = type.GetElementType();
|
||||||
else
|
|
||||||
underlyingType = type;
|
|
||||||
|
|
||||||
var reader = Module.Service.GetTypeReader(underlyingType);
|
var reader = Module.Service.GetTypeReader(type);
|
||||||
var underlyingTypeInfo = underlyingType.GetTypeInfo();
|
|
||||||
var typeInfo = type.GetTypeInfo();
|
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);
|
Module.Service.AddTypeReader(type, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +107,7 @@ namespace Discord.Commands
|
|||||||
bool isOptional = parameter.IsOptional;
|
bool isOptional = parameter.IsOptional;
|
||||||
object defaultValue = parameter.HasDefaultValue ? parameter.DefaultValue : null;
|
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();
|
return paramBuilder.ToImmutable();
|
||||||
}
|
}
|
||||||
@@ -118,8 +115,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
if (methodInfo.ReturnType != typeof(Task))
|
if (methodInfo.ReturnType != typeof(Task))
|
||||||
throw new InvalidOperationException("Commands must return a non-generic 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) =>
|
return (msg, args) =>
|
||||||
{
|
{
|
||||||
object[] newArgs = new object[args.Count + 1];
|
object[] newArgs = new object[args.Count + 1];
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.Commands
|
namespace Discord.Commands
|
||||||
{
|
{
|
||||||
//TODO: Add support for Multiple
|
|
||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class CommandParameter
|
public class CommandParameter
|
||||||
{
|
{
|
||||||
@@ -15,21 +13,19 @@ namespace Discord.Commands
|
|||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
public bool IsOptional { get; }
|
public bool IsOptional { get; }
|
||||||
public bool IsRemainder { get; }
|
public bool IsRemainder { get; }
|
||||||
public bool IsParams { get; }
|
public bool IsMultiple { get; }
|
||||||
public Type Type { get; }
|
public Type Type { get; }
|
||||||
public Type UnderlyingType { get; }
|
|
||||||
internal object DefaultValue { 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;
|
Name = name;
|
||||||
Description = description;
|
Description = description;
|
||||||
Type = type;
|
Type = type;
|
||||||
UnderlyingType = underlyingType;
|
|
||||||
_reader = reader;
|
_reader = reader;
|
||||||
IsOptional = isOptional;
|
IsOptional = isOptional;
|
||||||
IsRemainder = isRemainder;
|
IsRemainder = isRemainder;
|
||||||
IsParams = isParams;
|
IsMultiple = isMultiple;
|
||||||
DefaultValue = defaultValue;
|
DefaultValue = defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ namespace Discord.Commands
|
|||||||
int endPos = input.Length;
|
int endPos = input.Length;
|
||||||
var curPart = ParserPart.None;
|
var curPart = ParserPart.None;
|
||||||
int lastArgEndPos = int.MinValue;
|
int lastArgEndPos = int.MinValue;
|
||||||
IList<object> paramsList = null; // TODO: could we use a better type?
|
|
||||||
var argList = ImmutableArray.CreateBuilder<object>();
|
var argList = ImmutableArray.CreateBuilder<object>();
|
||||||
|
List<object> paramsList = null; // TODO: could we use a better type?
|
||||||
bool isEscaping = false;
|
bool isEscaping = false;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
@@ -74,10 +74,6 @@ namespace Discord.Commands
|
|||||||
argBuilder.Append(c);
|
argBuilder.Append(c);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (curParam != null && curParam.IsParams)
|
|
||||||
{
|
|
||||||
paramsList = new List<object>();
|
|
||||||
}
|
|
||||||
if (c == '\"')
|
if (c == '\"')
|
||||||
{
|
{
|
||||||
curPart = ParserPart.QuotedParameter;
|
curPart = ParserPart.QuotedParameter;
|
||||||
@@ -119,17 +115,17 @@ namespace Discord.Commands
|
|||||||
if (!typeReaderResult.IsSuccess)
|
if (!typeReaderResult.IsSuccess)
|
||||||
return ParseResult.FromError(typeReaderResult);
|
return ParseResult.FromError(typeReaderResult);
|
||||||
|
|
||||||
if (curParam.IsParams)
|
if (curParam.IsMultiple)
|
||||||
{
|
{
|
||||||
|
if (paramsList == null)
|
||||||
|
paramsList = new List<object>();
|
||||||
paramsList.Add(typeReaderResult.Value);
|
paramsList.Add(typeReaderResult.Value);
|
||||||
|
|
||||||
if (curPos == endPos)
|
if (curPos == endPos)
|
||||||
{
|
{
|
||||||
// TODO: can this logic be improved?
|
Array realParams = Array.CreateInstance(curParam.Type, paramsList.Count);
|
||||||
object[] _params = paramsList.ToArray();
|
for (int i = 0; i < paramsList.Count; i++)
|
||||||
Array realParams = Array.CreateInstance(curParam.UnderlyingType, _params.Length);
|
realParams.SetValue(Convert.ChangeType(paramsList[i], curParam.Type), i);
|
||||||
for (int i = 0; i < _params.Length; i++)
|
|
||||||
realParams.SetValue(Convert.ChangeType(_params[i], curParam.UnderlyingType), i);
|
|
||||||
|
|
||||||
argList.Add(realParams);
|
argList.Add(realParams);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user