Browse Source

Improve parameter precondition type safety

Also removes some terrible code which was left over when I first
implemented parameter preconditions. I don't know why that was there.

With this commit, parameter preconditions should be much safer as they
use generic methods instead of janky casting of objects.
pull/532/head
FiniteReality 8 years ago
parent
commit
c481966923
3 changed files with 17 additions and 10 deletions
  1. +1
    -1
      src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs
  2. +4
    -2
      src/Discord.Net.Commands/Info/CommandInfo.cs
  3. +12
    -7
      src/Discord.Net.Commands/Info/ParameterInfo.cs

+ 1
- 1
src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs View File

@@ -6,6 +6,6 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
public abstract class ParameterPreconditionAttribute : Attribute
{
public abstract Task<PreconditionResult> CheckPermissions(ICommandContext context, ParameterInfo parameter, object value, IDependencyMap map);
public abstract Task<PreconditionResult> CheckPermissions<T>(ICommandContext context, ParameterInfo parameter, T value, IDependencyMap map);
}
}

+ 4
- 2
src/Discord.Net.Commands/Info/CommandInfo.cs View File

@@ -128,9 +128,11 @@ namespace Discord.Commands
{
object[] args = GenerateArgs(argList, paramList);

foreach (var parameter in Parameters)
for (int position = 0; position < Parameters.Count; position++)
{
var result = await parameter.CheckPreconditionsAsync(context, args, map).ConfigureAwait(false);
var parameter = Parameters[position];
var argument = args[position];
var result = await parameter.CheckPreconditionsAsync(context, argument, map).ConfigureAwait(false);
if (!result.IsSuccess)
return ExecuteResult.FromError(result);
}


+ 12
- 7
src/Discord.Net.Commands/Info/ParameterInfo.cs View File

@@ -4,12 +4,18 @@ using System.Collections.Immutable;
using System.Threading.Tasks;

using Discord.Commands.Builders;
using System.Reflection;

namespace Discord.Commands
{
public class ParameterInfo
{

private static MethodInfo _checkPermissionsMethod = typeof(ParameterPreconditionAttribute)
.GetTypeInfo().GetDeclaredMethod("CheckPermissions");

private readonly TypeReader _reader;
private readonly MethodInfo _specializedCheckPermissionsMethod;

public CommandInfo Command { get; }
public string Name { get; }
@@ -38,21 +44,20 @@ namespace Discord.Commands
Preconditions = builder.Preconditions.ToImmutableArray();

_reader = builder.TypeReader;

_specializedCheckPermissionsMethod = _checkPermissionsMethod.MakeGenericMethod(Type);
}

public async Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, object[] args, IDependencyMap map = null)
public async Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, object arg, IDependencyMap map = null)
{
if (map == null)
map = DependencyMap.Empty;

int position = 0;
for(position = 0; position < Command.Parameters.Count; position++)
if (Command.Parameters[position] == this)
break;

foreach (var precondition in Preconditions)
{
var result = await precondition.CheckPermissions(context, this, args[position], map).ConfigureAwait(false);
object[] parameters = new []{ context, this, arg, map };
var resultTask = (_specializedCheckPermissionsMethod.Invoke(precondition, parameters) as Task<PreconditionResult>);
var result = await resultTask.ConfigureAwait(false);
if (!result.IsSuccess)
return result;
}


Loading…
Cancel
Save