From 9ba64f62d1013387231a98c00dc5d1dbb86bdb23 Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Wed, 2 Mar 2022 19:23:39 -0400
Subject: [PATCH] Interaction Service Complex Parameters (#2155)
* Interaction Service Complex Parameters
* add complex parameters
* add complex parameters
* fix build errors
* add argument parsing
* add nested complex parameter checks
* add inline docs
* add preferred constructor declaration
* fix autocompletehandlers for complex parameters
* make GetConstructor private
* use flattened params in ToProps method
* make DiscordType of SlashParameter nullable
* add docs to Flattened parameters collection and move the GetComplexParameterCtor method
* add inline docs to SlashCommandParameterBuilder.ComplexParameterFields
* add check for validating required/optinal parameter order
* implement change requests
* return internal ParseResult as ExecuteResult
Co-Authored-By: Cenk Ergen <57065323+Cenngo@users.noreply.github.com>
* fix merge errors
Co-authored-by: Cenk Ergen <57065323+Cenngo@users.noreply.github.com>
---
.../Attributes/ComplexParameterAttribute.cs | 30 +++++
.../ComplexParameterCtorAttribute.cs | 10 ++
.../Builders/ModuleClassBuilder.cs | 57 +++++++++-
.../SlashCommandParameterBuilder.cs | 68 +++++++++++-
.../Info/Commands/CommandInfo.cs | 3 +
.../Info/Commands/SlashCommandInfo.cs | 104 ++++++++++++++----
.../Parameters/SlashCommandParameterInfo.cs | 30 ++++-
.../InteractionService.cs | 4 +-
.../Results/ParseResult.cs | 36 ++++++
.../Utilities/ApplicationCommandRestUtil.cs | 6 +-
10 files changed, 315 insertions(+), 33 deletions(-)
create mode 100644 src/Discord.Net.Interactions/Attributes/ComplexParameterAttribute.cs
create mode 100644 src/Discord.Net.Interactions/Attributes/ComplexParameterCtorAttribute.cs
create mode 100644 src/Discord.Net.Interactions/Results/ParseResult.cs
diff --git a/src/Discord.Net.Interactions/Attributes/ComplexParameterAttribute.cs b/src/Discord.Net.Interactions/Attributes/ComplexParameterAttribute.cs
new file mode 100644
index 000000000..952ca06a4
--- /dev/null
+++ b/src/Discord.Net.Interactions/Attributes/ComplexParameterAttribute.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace Discord.Interactions
+{
+ ///
+ /// Registers a parameter as a complex parameter.
+ ///
+ [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
+ public class ComplexParameterAttribute : Attribute
+ {
+ ///
+ /// Gets the parameter array of the constructor method that should be prioritized.
+ ///
+ public Type[] PrioritizedCtorSignature { get; }
+
+ ///
+ /// Registers a slash command parameter as a complex parameter.
+ ///
+ public ComplexParameterAttribute() { }
+
+ ///
+ /// Registers a slash command parameter as a complex parameter with a specified constructor signature.
+ ///
+ /// Type array of the preferred constructor parameters.
+ public ComplexParameterAttribute(Type[] types)
+ {
+ PrioritizedCtorSignature = types;
+ }
+ }
+}
diff --git a/src/Discord.Net.Interactions/Attributes/ComplexParameterCtorAttribute.cs b/src/Discord.Net.Interactions/Attributes/ComplexParameterCtorAttribute.cs
new file mode 100644
index 000000000..59ee3377b
--- /dev/null
+++ b/src/Discord.Net.Interactions/Attributes/ComplexParameterCtorAttribute.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Discord.Interactions
+{
+ ///
+ /// Tag a type constructor as the preferred Complex command constructor.
+ ///
+ [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)]
+ public class ComplexParameterCtorAttribute : Attribute { }
+}
diff --git a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs
index 6615f131c..88a34f3b2 100644
--- a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs
+++ b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs
@@ -397,7 +397,6 @@ namespace Discord.Interactions.Builders
builder.Description = paramInfo.Name;
builder.IsRequired = !paramInfo.IsOptional;
builder.DefaultValue = paramInfo.DefaultValue;
- builder.SetParameterType(paramType, services);
foreach (var attribute in attributes)
{
@@ -435,12 +434,32 @@ namespace Discord.Interactions.Builders
case MinValueAttribute minValue:
builder.MinValue = minValue.Value;
break;
+ case ComplexParameterAttribute complexParameter:
+ {
+ builder.IsComplexParameter = true;
+ ConstructorInfo ctor = GetComplexParameterConstructor(paramInfo.ParameterType.GetTypeInfo(), complexParameter);
+
+ foreach (var parameter in ctor.GetParameters())
+ {
+ if (parameter.IsDefined(typeof(ComplexParameterAttribute)))
+ throw new InvalidOperationException("You cannot create nested complex parameters.");
+
+ builder.AddComplexParameterField(fieldBuilder => BuildSlashParameter(fieldBuilder, parameter, services));
+ }
+
+ var initializer = builder.Command.Module.InteractionService._useCompiledLambda ?
+ ReflectionUtils