diff options
author | Shockah <me@shockah.pl> | 2022-02-08 20:02:13 +0100 |
---|---|---|
committer | Shockah <me@shockah.pl> | 2022-02-08 20:02:13 +0100 |
commit | 0ff82c38e7a5b630256d2cd23a63ac1088d13e39 (patch) | |
tree | a80c338fd836f324b2cc2e5b0fb43f0b39df9d82 /src | |
parent | 25a9f54ecfdaf6c4ad67dfb46c3f8c556d15d949 (diff) | |
download | SMAPI-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.cs | 31 |
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."); |