Browse Source

Merge d7794f0baa into 724dbf0abf

pull/161/merge
DigiTechs GitHub 9 years ago
parent
commit
265cd3efe3
3 changed files with 51 additions and 8 deletions
  1. +13
    -4
      src/Discord.Net.Commands/Command.cs
  2. +5
    -1
      src/Discord.Net.Commands/CommandParameter.cs
  3. +33
    -3
      src/Discord.Net.Commands/CommandParser.cs

+ 13
- 4
src/Discord.Net.Commands/Command.cs View File

@@ -71,6 +71,7 @@ namespace Discord.Commands
{
var parameter = parameters[i];
var type = parameter.ParameterType;
Type underlyingType = null;

if (i == 0)
{
@@ -80,12 +81,20 @@ 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;

var reader = Module.Service.GetTypeReader(underlyingType);
var underlyingTypeInfo = underlyingType.GetTypeInfo();
var typeInfo = type.GetTypeInfo();
var reader = Module.Service.GetTypeReader(type);

if (reader == null && typeInfo.IsEnum)
if (reader == null && underlyingTypeInfo.IsEnum)
{
reader = EnumTypeReader.GetReader(type);
reader = EnumTypeReader.GetReader(underlyingType);
Module.Service.AddTypeReader(type, reader);
}

@@ -101,7 +110,7 @@ namespace Discord.Commands
bool isOptional = parameter.IsOptional;
object defaultValue = parameter.HasDefaultValue ? parameter.DefaultValue : null;

paramBuilder.Add(new CommandParameter(name, description, type, reader, isOptional, isRemainder, defaultValue));
paramBuilder.Add(new CommandParameter(name, description, type, underlyingType, reader, isOptional, isRemainder, isParams, defaultValue));
}
return paramBuilder.ToImmutable();
}


+ 5
- 1
src/Discord.Net.Commands/CommandParameter.cs View File

@@ -15,17 +15,21 @@ namespace Discord.Commands
public string Description { get; }
public bool IsOptional { get; }
public bool IsRemainder { get; }
public bool IsParams { get; }
public Type Type { get; }
public Type UnderlyingType { get; }
internal object DefaultValue { get; }

public CommandParameter(string name, string description, Type type, TypeReader reader, bool isOptional, bool isRemainder, object defaultValue)
public CommandParameter(string name, string description, Type type, Type underlyingType, TypeReader reader, bool isOptional, bool isRemainder, bool isParams, object defaultValue)
{
Name = name;
Description = description;
Type = type;
UnderlyingType = underlyingType;
_reader = reader;
IsOptional = isOptional;
IsRemainder = isRemainder;
IsParams = isParams;
DefaultValue = defaultValue;
}



+ 33
- 3
src/Discord.Net.Commands/CommandParser.cs View File

@@ -1,6 +1,9 @@
using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System;

namespace Discord.Commands
{
@@ -20,6 +23,7 @@ namespace Discord.Commands
int endPos = input.Length;
var curPart = ParserPart.None;
int lastArgEndPos = int.MinValue;
IList<object> paramsList = null; // TODO: could we use a better type?
var argList = ImmutableArray.CreateBuilder<object>();
bool isEscaping = false;
char c;
@@ -70,6 +74,10 @@ namespace Discord.Commands
argBuilder.Append(c);
continue;
}
if (curParam != null && curParam.IsParams)
{
paramsList = new List<object>();
}
if (c == '\"')
{
curPart = ParserPart.QuotedParameter;
@@ -110,10 +118,32 @@ namespace Discord.Commands
var typeReaderResult = await curParam.Parse(context, argString).ConfigureAwait(false);
if (!typeReaderResult.IsSuccess)
return ParseResult.FromError(typeReaderResult);
argList.Add(typeReaderResult.Value);

curParam = null;
curPart = ParserPart.None;
if (curParam.IsParams)
{
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);

argList.Add(realParams);

curParam = null;
curPart = ParserPart.None;
}
}
else
{
argList.Add(typeReaderResult.Value);

curParam = null;
curPart = ParserPart.None;
}
argBuilder.Clear();
}
}


Loading…
Cancel
Save