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 parameter = parameters[i];
var type = parameter.ParameterType; var type = parameter.ParameterType;
Type underlyingType = null;


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

var reader = Module.Service.GetTypeReader(underlyingType);
var underlyingTypeInfo = underlyingType.GetTypeInfo();
var typeInfo = type.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); Module.Service.AddTypeReader(type, reader);
} }


@@ -101,7 +110,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, reader, isOptional, isRemainder, defaultValue));
paramBuilder.Add(new CommandParameter(name, description, type, underlyingType, reader, isOptional, isRemainder, isParams, defaultValue));
} }
return paramBuilder.ToImmutable(); 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 string Description { get; }
public bool IsOptional { get; } public bool IsOptional { get; }
public bool IsRemainder { get; } public bool IsRemainder { get; }
public bool IsParams { 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, 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; 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;
DefaultValue = defaultValue; DefaultValue = defaultValue;
} }




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

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


namespace Discord.Commands namespace Discord.Commands
{ {
@@ -20,6 +23,7 @@ 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>();
bool isEscaping = false; bool isEscaping = false;
char c; char c;
@@ -70,6 +74,10 @@ 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;
@@ -110,10 +118,32 @@ namespace Discord.Commands
var typeReaderResult = await curParam.Parse(context, argString).ConfigureAwait(false); var typeReaderResult = await curParam.Parse(context, argString).ConfigureAwait(false);
if (!typeReaderResult.IsSuccess) if (!typeReaderResult.IsSuccess)
return ParseResult.FromError(typeReaderResult); 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(); argBuilder.Clear();
} }
} }


Loading…
Cancel
Save