Add various optimizations and cleanups (#1114)
* Change all Select(... as ...) to OfType
* Add changes according to 194a8aa427
This commit is contained in:
@@ -7,13 +7,13 @@ namespace Discord.Commands
|
||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
|
||||
public class OverrideTypeReaderAttribute : Attribute
|
||||
{
|
||||
private static readonly TypeInfo _typeReaderTypeInfo = typeof(TypeReader).GetTypeInfo();
|
||||
private static readonly TypeInfo TypeReaderTypeInfo = typeof(TypeReader).GetTypeInfo();
|
||||
|
||||
public Type TypeReader { get; }
|
||||
|
||||
public OverrideTypeReaderAttribute(Type overridenTypeReader)
|
||||
{
|
||||
if (!_typeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo()))
|
||||
if (!TypeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo()))
|
||||
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}");
|
||||
|
||||
TypeReader = overridenTypeReader;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Discord.Commands
|
||||
{
|
||||
internal static class ModuleClassBuilder
|
||||
{
|
||||
private static readonly TypeInfo _moduleTypeInfo = typeof(IModuleBase).GetTypeInfo();
|
||||
private static readonly TypeInfo ModuleTypeInfo = typeof(IModuleBase).GetTypeInfo();
|
||||
|
||||
public static async Task<IReadOnlyList<TypeInfo>> SearchAsync(Assembly assembly, CommandService service)
|
||||
{
|
||||
@@ -135,7 +135,7 @@ namespace Discord.Commands
|
||||
if (builder.Name == null)
|
||||
builder.Name = typeInfo.Name;
|
||||
|
||||
var validCommands = typeInfo.DeclaredMethods.Where(x => IsValidCommandDefinition(x));
|
||||
var validCommands = typeInfo.DeclaredMethods.Where(IsValidCommandDefinition);
|
||||
|
||||
foreach (var method in validCommands)
|
||||
{
|
||||
@@ -299,7 +299,7 @@ namespace Discord.Commands
|
||||
|
||||
private static bool IsValidModuleDefinition(TypeInfo typeInfo)
|
||||
{
|
||||
return _moduleTypeInfo.IsAssignableFrom(typeInfo) &&
|
||||
return ModuleTypeInfo.IsAssignableFrom(typeInfo) &&
|
||||
!typeInfo.IsAbstract &&
|
||||
!typeInfo.ContainsGenericParameters;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace Discord.Commands
|
||||
var typeInfo = type.GetTypeInfo();
|
||||
|
||||
if (_typedModuleDefs.ContainsKey(type))
|
||||
throw new ArgumentException($"This module has already been added.");
|
||||
throw new ArgumentException("This module has already been added.");
|
||||
|
||||
var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault();
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace Discord.Commands
|
||||
{
|
||||
if (_defaultTypeReaders.ContainsKey(type))
|
||||
_ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." +
|
||||
$"To suppress this message, use AddTypeReader<T>(reader, true).");
|
||||
"To suppress this message, use AddTypeReader<T>(reader, true).");
|
||||
AddTypeReader(type, reader, true);
|
||||
}
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Discord.Commands.Builders;
|
||||
using Discord.Commands.Builders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
@@ -63,7 +63,7 @@ namespace Discord.Commands
|
||||
Attributes = builder.Attributes.ToImmutableArray();
|
||||
|
||||
Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray();
|
||||
HasVarArgs = builder.Parameters.Count > 0 ? builder.Parameters[builder.Parameters.Count - 1].IsMultiple : false;
|
||||
HasVarArgs = builder.Parameters.Count > 0 && builder.Parameters[builder.Parameters.Count - 1].IsMultiple;
|
||||
IgnoreExtraArgs = builder.IgnoreExtraArgs;
|
||||
|
||||
_action = builder.Callback;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
@@ -6,7 +6,7 @@ namespace Discord.Commands
|
||||
{
|
||||
private readonly CommandService _service;
|
||||
private readonly CommandMapNode _root;
|
||||
private static readonly string[] _blankAliases = new[] { "" };
|
||||
private static readonly string[] BlankAliases = { "" };
|
||||
|
||||
public CommandMap(CommandService service)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
@@ -7,7 +7,7 @@ namespace Discord.Commands
|
||||
{
|
||||
internal class CommandMapNode
|
||||
{
|
||||
private static readonly char[] _whitespaceChars = new[] { ' ', '\r', '\n' };
|
||||
private static readonly char[] WhitespaceChars = { ' ', '\r', '\n' };
|
||||
|
||||
private readonly ConcurrentDictionary<string, CommandMapNode> _nodes;
|
||||
private readonly string _name;
|
||||
@@ -52,7 +52,6 @@ namespace Discord.Commands
|
||||
public void RemoveCommand(CommandService service, string text, int index, CommandInfo command)
|
||||
{
|
||||
int nextSegment = NextSegment(text, index, service._separatorChar);
|
||||
string name;
|
||||
|
||||
lock (_lockObj)
|
||||
{
|
||||
@@ -60,13 +59,13 @@ namespace Discord.Commands
|
||||
_commands = _commands.Remove(command);
|
||||
else
|
||||
{
|
||||
string name;
|
||||
if (nextSegment == -1)
|
||||
name = text.Substring(index);
|
||||
else
|
||||
name = text.Substring(index, nextSegment - index);
|
||||
|
||||
CommandMapNode nextNode;
|
||||
if (_nodes.TryGetValue(name, out nextNode))
|
||||
if (_nodes.TryGetValue(name, out var nextNode))
|
||||
{
|
||||
nextNode.RemoveCommand(service, nextSegment == -1 ? "" : text, nextSegment + 1, command);
|
||||
if (nextNode.IsEmpty)
|
||||
@@ -100,7 +99,7 @@ namespace Discord.Commands
|
||||
}
|
||||
|
||||
//Check if this is the last command segment before args
|
||||
nextSegment = NextSegment(text, index, _whitespaceChars, service._separatorChar);
|
||||
nextSegment = NextSegment(text, index, WhitespaceChars, service._separatorChar);
|
||||
if (nextSegment != -1)
|
||||
{
|
||||
name = text.Substring(index, nextSegment - index);
|
||||
|
||||
@@ -8,9 +8,9 @@ namespace Discord.Commands
|
||||
|
||||
internal static class PrimitiveParsers
|
||||
{
|
||||
private static readonly Lazy<IReadOnlyDictionary<Type, Delegate>> _parsers = new Lazy<IReadOnlyDictionary<Type, Delegate>>(CreateParsers);
|
||||
private static readonly Lazy<IReadOnlyDictionary<Type, Delegate>> Parsers = new Lazy<IReadOnlyDictionary<Type, Delegate>>(CreateParsers);
|
||||
|
||||
public static IEnumerable<Type> SupportedTypes = _parsers.Value.Keys;
|
||||
public static IEnumerable<Type> SupportedTypes = Parsers.Value.Keys;
|
||||
|
||||
static IReadOnlyDictionary<Type, Delegate> CreateParsers()
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace Discord.Commands
|
||||
return parserBuilder.ToImmutable();
|
||||
}
|
||||
|
||||
public static TryParseDelegate<T> Get<T>() => (TryParseDelegate<T>)_parsers.Value[typeof(T)];
|
||||
public static Delegate Get(Type type) => _parsers.Value[type];
|
||||
public static TryParseDelegate<T> Get<T>() => (TryParseDelegate<T>)Parsers.Value[typeof(T)];
|
||||
public static Delegate Get(Type type) => Parsers.Value[type];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ namespace Discord.Commands
|
||||
{
|
||||
internal class TimeSpanTypeReader : TypeReader
|
||||
{
|
||||
private static readonly string[] _formats = new[]
|
||||
{
|
||||
private static readonly string[] Formats = {
|
||||
"%d'd'%h'h'%m'm'%s's'", //4d3h2m1s
|
||||
"%d'd'%h'h'%m'm'", //4d3h2m
|
||||
"%d'd'%h'h'%s's'", //4d3h 1s
|
||||
@@ -27,7 +26,7 @@ namespace Discord.Commands
|
||||
|
||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
return (TimeSpan.TryParseExact(input.ToLowerInvariant(), _formats, CultureInfo.InvariantCulture, out var timeSpan))
|
||||
return (TimeSpan.TryParseExact(input.ToLowerInvariant(), Formats, CultureInfo.InvariantCulture, out var timeSpan))
|
||||
? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan))
|
||||
: Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan"));
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ namespace Discord.Commands
|
||||
.Where(x => string.Equals(input, (x as IGuildUser)?.Nickname, StringComparison.OrdinalIgnoreCase))
|
||||
.ForEachAsync(channelUser => AddResult(results, channelUser as T, (channelUser as IGuildUser).Nickname == input ? 0.65f : 0.55f));
|
||||
|
||||
foreach (var guildUser in guildUsers.Where(x => string.Equals(input, (x as IGuildUser).Nickname, StringComparison.OrdinalIgnoreCase)))
|
||||
AddResult(results, guildUser as T, (guildUser as IGuildUser).Nickname == input ? 0.60f : 0.50f);
|
||||
foreach (var guildUser in guildUsers.Where(x => string.Equals(input, x.Nickname, StringComparison.OrdinalIgnoreCase)))
|
||||
AddResult(results, guildUser as T, guildUser.Nickname == input ? 0.60f : 0.50f);
|
||||
}
|
||||
|
||||
if (results.Count > 0)
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Discord.Commands
|
||||
{
|
||||
internal static class ReflectionUtils
|
||||
{
|
||||
private static readonly TypeInfo _objectTypeInfo = typeof(object).GetTypeInfo();
|
||||
private static readonly TypeInfo ObjectTypeInfo = typeof(object).GetTypeInfo();
|
||||
|
||||
internal static T CreateObject<T>(TypeInfo typeInfo, CommandService commands, IServiceProvider services = null)
|
||||
=> CreateBuilder<T>(typeInfo, commands)(services);
|
||||
@@ -54,7 +54,7 @@ namespace Discord.Commands
|
||||
private static System.Reflection.PropertyInfo[] GetProperties(TypeInfo ownerType)
|
||||
{
|
||||
var result = new List<System.Reflection.PropertyInfo>();
|
||||
while (ownerType != _objectTypeInfo)
|
||||
while (ownerType != ObjectTypeInfo)
|
||||
{
|
||||
foreach (var prop in ownerType.DeclaredProperties)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user