From 1ff09685906b03b46b23e69b7bfe95df24c8184f Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com>
Date: Sat, 9 May 2020 20:45:45 -0400
Subject: fixed generic types in method references not rewritten (#711)

---
 src/SMAPI/Framework/ModLoading/AssemblyLoader.cs      |  8 +++++++-
 .../Framework/ModLoading/Framework/BaseTypeFinder.cs  | 19 +++++++++++++++----
 .../ModLoading/Framework/BaseTypeReferenceRewriter.cs |  5 +++++
 3 files changed, 27 insertions(+), 5 deletions(-)

(limited to 'src/SMAPI/Framework')

diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
index 5b5a621b..570686fe 100644
--- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
+++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
@@ -314,13 +314,19 @@ namespace StardewModdingAPI.Framework.ModLoading
                     // ReSharper disable once ForCanBeConvertedToForeach -- deliberate access by index so each handler sees replacements from previous handlers
                     for (int offset = 0; offset < instructions.Count; offset++)
                     {
+                        Instruction instruction = instructions[offset];
+                        if (instruction.OpCode.Code == Code.Nop)
+                            continue;
+
                         foreach (IInstructionHandler handler in handlers)
                         {
-                            Instruction instruction = instructions[offset];
                             InstructionHandleResult result = handler.Handle(module, cil, instruction, this.AssemblyMap, platformChanged);
                             this.ProcessInstructionHandleResult(mod, handler, result, loggedMessages, logPrefix, filename);
                             if (result == InstructionHandleResult.Rewritten)
+                            {
+                                instruction = instructions[offset];
                                 anyRewritten = true;
+                            }
                         }
                     }
                 }
diff --git a/src/SMAPI/Framework/ModLoading/Framework/BaseTypeFinder.cs b/src/SMAPI/Framework/ModLoading/Framework/BaseTypeFinder.cs
index 48165c4c..04b2e08d 100644
--- a/src/SMAPI/Framework/ModLoading/Framework/BaseTypeFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Framework/BaseTypeFinder.cs
@@ -108,10 +108,21 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
             MethodReference methodRef = RewriteHelper.AsMethodReference(instruction);
             if (methodRef != null)
             {
-                return
-                    this.IsMatch(methodRef.DeclaringType) // method on target class
-                    || this.IsMatch(methodRef.ReturnType) // method returns target class
-                    || methodRef.Parameters.Any(p => this.IsMatch(p.ParameterType)); // method parameters
+                // method on target class
+                if (this.IsMatch(methodRef.DeclaringType))
+                    return true;
+
+                // method returns target class
+                if (this.IsMatch(methodRef.ReturnType))
+                    return true;
+
+                // method parameters of target class
+                if (methodRef.Parameters.Any(p => this.IsMatch(p.ParameterType)))
+                    return true;
+
+                // generic args of target class
+                if (methodRef is GenericInstanceMethod genericRef && genericRef.GenericArguments.Any(this.IsMatch))
+                    return true;
             }
 
             return false;
diff --git a/src/SMAPI/Framework/ModLoading/Framework/BaseTypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Framework/BaseTypeReferenceRewriter.cs
index 445ac2cb..3ccacf22 100644
--- a/src/SMAPI/Framework/ModLoading/Framework/BaseTypeReferenceRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Framework/BaseTypeReferenceRewriter.cs
@@ -104,6 +104,11 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
                 rewritten |= this.RewriteIfNeeded(module, methodRef.ReturnType, newType => methodRef.ReturnType = newType);
                 foreach (var parameter in methodRef.Parameters)
                     rewritten |= this.RewriteIfNeeded(module, parameter.ParameterType, newType => parameter.ParameterType = newType);
+                if (methodRef is GenericInstanceMethod genericRef)
+                {
+                    for (int i = 0; i < genericRef.GenericArguments.Count; i++)
+                        rewritten |= this.RewriteIfNeeded(module, genericRef.GenericArguments[i], newType => genericRef.GenericArguments[i] = newType);
+                }
             }
 
             // type reference
-- 
cgit