Browse Source

Merge 546831f72c into f417c2b516

pull/287/merge
Joe4evr GitHub 8 years ago
parent
commit
03d0d143f0
4 changed files with 70 additions and 15 deletions
  1. +36
    -0
      src/Discord.Net.Commands/Attributes/TypeReaderAttribute.cs
  2. +10
    -4
      src/Discord.Net.Commands/CommandInfo.cs
  3. +6
    -6
      src/Discord.Net.Commands/CommandService.cs
  4. +18
    -5
      src/Discord.Net.Commands/ModuleInfo.cs

+ 36
- 0
src/Discord.Net.Commands/Attributes/TypeReaderAttribute.cs View File

@@ -0,0 +1,36 @@
using System;
using System.Reflection;

namespace Discord.Commands
{
/// <summary>
/// Allows to override the <see cref="TypeReader"/> used for a parameter/type.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = true)]
public class TypeReaderAttribute : Attribute
{
/// <summary>
/// Type of the type that is read.
/// </summary>
public Type Type { get; }

/// <summary>
/// <see cref="TypeInfo"/> of the specified <see cref="TypeReader"/>.
/// </summary>
public TypeInfo OverridingTypeReader { get; }

/// <summary>
/// Specify a <see cref="TypeReader"/> for a particular type.
/// </summary>
/// <param name="forType">Type of the type to read.</param>
/// <param name="typeReader">Type of the <see cref="TypeReader"/> that reads the type.</param>
public TypeReaderAttribute(Type forType, Type typeReader)
{
if (!typeof(TypeReader).GetTypeInfo().IsAssignableFrom(typeReader.GetTypeInfo()))
throw new ArgumentException($"Type of argument {nameof(typeReader)} must derive from {nameof(TypeReader)}", nameof(typeReader));

Type = forType;
OverridingTypeReader = typeReader.GetTypeInfo();
}
}
}

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

@@ -30,7 +30,7 @@ namespace Discord.Commands
public IReadOnlyList<CommandParameter> Parameters { get; }
public IReadOnlyList<PreconditionAttribute> Preconditions { get; }

internal CommandInfo(MethodInfo source, ModuleInfo module, CommandAttribute attribute, string groupPrefix)
internal CommandInfo(MethodInfo source, ModuleInfo module, CommandAttribute attribute, string groupPrefix, IDependencyMap dependencyMap = null)
{
try
{
@@ -74,7 +74,7 @@ namespace Discord.Commands
var priorityAttr = source.GetCustomAttribute<PriorityAttribute>();
Priority = priorityAttr?.Priority ?? 0;

Parameters = BuildParameters(source);
Parameters = BuildParameters(source, dependencyMap);
HasVarArgs = Parameters.Count > 0 ? Parameters[Parameters.Count - 1].IsMultiple : false;
Preconditions = BuildPreconditions(source);
_action = BuildAction(source);
@@ -184,7 +184,7 @@ namespace Discord.Commands
return methodInfo.GetCustomAttributes<PreconditionAttribute>().ToImmutableArray();
}

private IReadOnlyList<CommandParameter> BuildParameters(MethodInfo methodInfo)
private IReadOnlyList<CommandParameter> BuildParameters(MethodInfo methodInfo, IDependencyMap dependencyMap = null)
{
var parameters = methodInfo.GetParameters();

@@ -199,7 +199,13 @@ namespace Discord.Commands
if (isMultiple)
type = type.GetElementType();

var reader = Module.Service.GetTypeReader(type);
var trAttr = parameter.GetCustomAttribute<TypeReaderAttribute>();

var reader = (trAttr != null && trAttr.Type == type) ?
ReflectionUtils.CreateObject<TypeReader>(trAttr.OverridingTypeReader, Module.Service, dependencyMap) :
(Module.OverridingTypeReaders.ContainsKey(type) ?
Module.OverridingTypeReaders[type] :
Module.Service.GetTypeReader(type));
var typeInfo = type.GetTypeInfo();

//Detect enums


+ 6
- 6
src/Discord.Net.Commands/CommandService.cs View File

@@ -65,7 +65,7 @@ namespace Discord.Commands
}

//Modules
public async Task<ModuleInfo> AddModule<T>()
public async Task<ModuleInfo> AddModule<T>(IDependencyMap dependencyMap = null)
{
await _moduleLock.WaitAsync().ConfigureAwait(false);
try
@@ -80,14 +80,14 @@ namespace Discord.Commands
if (_moduleDefs.ContainsKey(typeof(T)))
throw new ArgumentException($"This module has already been added.");

return AddModuleInternal(typeInfo);
return AddModuleInternal(typeInfo, dependencyMap);
}
finally
{
_moduleLock.Release();
}
}
public async Task<IEnumerable<ModuleInfo>> AddModules(Assembly assembly)
public async Task<IEnumerable<ModuleInfo>> AddModules(Assembly assembly, IDependencyMap dependencyMap = null)
{
var moduleDefs = ImmutableArray.CreateBuilder<ModuleInfo>();
await _moduleLock.WaitAsync().ConfigureAwait(false);
@@ -102,7 +102,7 @@ namespace Discord.Commands
{
var dontAutoLoad = typeInfo.GetCustomAttribute<DontAutoLoadAttribute>();
if (dontAutoLoad == null && !typeInfo.IsAbstract)
moduleDefs.Add(AddModuleInternal(typeInfo));
moduleDefs.Add(AddModuleInternal(typeInfo, dependencyMap));
}
}
}
@@ -113,9 +113,9 @@ namespace Discord.Commands
_moduleLock.Release();
}
}
private ModuleInfo AddModuleInternal(TypeInfo typeInfo)
private ModuleInfo AddModuleInternal(TypeInfo typeInfo, IDependencyMap dependencyMap = null)
{
var moduleDef = new ModuleInfo(typeInfo, this);
var moduleDef = new ModuleInfo(typeInfo, this, dependencyMap);
_moduleDefs[typeInfo.AsType()] = moduleDef;

foreach (var cmd in moduleDef.Commands)


+ 18
- 5
src/Discord.Net.Commands/ModuleInfo.cs View File

@@ -19,8 +19,9 @@ namespace Discord.Commands
public string Remarks { get; }
public IEnumerable<CommandInfo> Commands { get; }
public IReadOnlyList<PreconditionAttribute> Preconditions { get; }
public ImmutableDictionary<Type, TypeReader> OverridingTypeReaders { get; }

internal ModuleInfo(TypeInfo source, CommandService service)
internal ModuleInfo(TypeInfo source, CommandService service, IDependencyMap dependencyMap = null)
{
Source = source;
Service = service;
@@ -45,19 +46,31 @@ namespace Discord.Commands
if (remarksAttr != null)
Remarks = remarksAttr.Text;

var typeReaders = new Dictionary<Type, TypeReader>();

var trAttrs = source.GetCustomAttributes<TypeReaderAttribute>();
foreach (var trAttr in trAttrs)
typeReaders[trAttr.Type] = GetOverridingTypeReader(trAttr, dependencyMap);

OverridingTypeReaders = typeReaders.ToImmutableDictionary();

List<CommandInfo> commands = new List<CommandInfo>();
SearchClass(source, commands, Prefix);
SearchClass(source, commands, Prefix, dependencyMap);
Commands = commands;

Preconditions = Source.GetCustomAttributes<PreconditionAttribute>().ToImmutableArray();
}
private void SearchClass(TypeInfo parentType, List<CommandInfo> commands, string groupPrefix)

private TypeReader GetOverridingTypeReader(TypeReaderAttribute trAttr, IDependencyMap dependencyMap = null)
=> ReflectionUtils.CreateObject<TypeReader>(trAttr.OverridingTypeReader, Service, dependencyMap);

private void SearchClass(TypeInfo parentType, List<CommandInfo> commands, string groupPrefix, IDependencyMap dependencyMap = null)
{
foreach (var method in parentType.DeclaredMethods)
{
var cmdAttr = method.GetCustomAttribute<CommandAttribute>();
if (cmdAttr != null)
commands.Add(new CommandInfo(method, this, cmdAttr, groupPrefix));
commands.Add(new CommandInfo(method, this, cmdAttr, groupPrefix, dependencyMap));
}
foreach (var type in parentType.DeclaredNestedTypes)
{
@@ -71,7 +84,7 @@ namespace Discord.Commands
else
nextGroupPrefix = groupAttrib.Prefix ?? type.Name.ToLowerInvariant();

SearchClass(type, commands, nextGroupPrefix);
SearchClass(type, commands, nextGroupPrefix, dependencyMap);
}
}
}


Loading…
Cancel
Save