summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShockah <me@shockah.pl>2022-02-08 20:02:13 +0100
committerShockah <me@shockah.pl>2022-02-08 20:02:13 +0100
commit0ff82c38e7a5b630256d2cd23a63ac1088d13e39 (patch)
treea80c338fd836f324b2cc2e5b0fb43f0b39df9d82 /src
parent25a9f54ecfdaf6c4ad67dfb46c3f8c556d15d949 (diff)
downloadSMAPI-0ff82c38e7a5b630256d2cd23a63ac1088d13e39.tar.gz
SMAPI-0ff82c38e7a5b630256d2cd23a63ac1088d13e39.tar.bz2
SMAPI-0ff82c38e7a5b630256d2cd23a63ac1088d13e39.zip
allow default interface method implementations in API proxies
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs b/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs
index 70ef81f8..164cac0b 100644
--- a/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs
+++ b/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs
@@ -55,10 +55,39 @@ namespace StardewModdingAPI.Framework.Reflection
il.Emit(OpCodes.Ret);
}
+ var allTargetMethods = targetType.GetMethods().ToList();
+ foreach (Type targetInterface in targetType.GetInterfaces())
+ {
+ foreach (MethodInfo targetMethod in targetInterface.GetMethods())
+ {
+ if (!targetMethod.IsAbstract)
+ allTargetMethods.Add(targetMethod);
+ }
+ }
+
// proxy methods
foreach (MethodInfo proxyMethod in interfaceType.GetMethods())
{
- var targetMethod = targetType.GetMethod(proxyMethod.Name, proxyMethod.GetParameters().Select(a => a.ParameterType).ToArray());
+ var proxyMethodParameters = proxyMethod.GetParameters();
+ var targetMethod = allTargetMethods.Where(m =>
+ {
+ if (m.Name != proxyMethod.Name)
+ return false;
+ if (m.ReturnType != proxyMethod.ReturnType)
+ return false;
+
+ var mParameters = m.GetParameters();
+ if (m.GetParameters().Length != proxyMethodParameters.Length)
+ return false;
+ for (int i = 0; i < mParameters.Length; i++)
+ {
+ // TODO: decide if "assignable" checking is desired (instead of just 1:1 type equality)
+ // TODO: test if this actually works
+ if (!mParameters[i].ParameterType.IsAssignableFrom(proxyMethodParameters[i].ParameterType))
+ return false;
+ }
+ return true;
+ }).FirstOrDefault();
if (targetMethod == null)
throw new InvalidOperationException($"The {interfaceType.FullName} interface defines method {proxyMethod.Name} which doesn't exist in the API.");