Browse Source

Cleaned up params implementation

tags/1.0-rc
RogueException 8 years ago
parent
commit
a04cf5201a
3 changed files with 20 additions and 32 deletions
  1. +10
    -14
      src/Discord.Net.Commands/Command.cs
  2. +3
    -7
      src/Discord.Net.Commands/CommandParameter.cs
  3. +7
    -11
      src/Discord.Net.Commands/CommandParser.cs

+ 10
- 14
src/Discord.Net.Commands/Command.cs View File

@@ -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'?
bool isParams = type.IsArray && i == parameters.Length - 1;
if (isParams)
underlyingType = type.GetElementType();
else
underlyingType = type;
//Detect 'params'
bool isMultiple = parameter.GetCustomAttribute<ParamArrayAttribute>() != 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(); 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];


+ 3
- 7
src/Discord.Net.Commands/CommandParameter.cs View File

@@ -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;
} }




+ 7
- 11
src/Discord.Net.Commands/CommandParser.cs View File

@@ -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?
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); argList.Add(realParams);




Loading…
Cancel
Save