From 911957d582d471dcb9ab1d3762273620269c87f4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 26 Mar 2017 19:21:24 -0400 Subject: [PATCH] fix type finder not matching generic type parameters (#254) --- .../Finders/TypeFinder.cs | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs index 0e4d6824..0560e38e 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs +++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs @@ -72,12 +72,12 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders /// The method deifnition. protected bool IsMatch(MethodDefinition method) { - if (method.ReturnType.FullName == this.FullTypeName) + if (this.IsMatch(method.ReturnType)) return true; foreach (VariableDefinition variable in method.Body.Variables) { - if (variable.VariableType.FullName == this.FullTypeName) + if (this.IsMatch(variable.VariableType)) return true; } @@ -88,15 +88,13 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders /// The IL instruction. protected bool IsMatch(Instruction instruction) { - string fullName = this.FullTypeName; - // field reference FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); if (fieldRef != null) { return - fieldRef.DeclaringType.FullName == fullName // field on target class - || fieldRef.FieldType.FullName == fullName; // field value is target class + this.IsMatch(fieldRef.DeclaringType) // field on target class + || this.IsMatch(fieldRef.FieldType); // field value is target class } // method reference @@ -104,12 +102,34 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders if (methodRef != null) { return - methodRef.DeclaringType.FullName == fullName // method on target class - || methodRef.ReturnType.FullName == fullName // method returns target class - || methodRef.Parameters.Any(p => p.ParameterType.FullName == fullName); // method parameters + 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 } return false; } + + /// Get whether a type reference matches the expected type. + /// The type to check. + protected bool IsMatch(TypeReference type) + { + // root type + if (type.FullName == this.FullTypeName) + return true; + + // generic arguments + if (type is GenericInstanceType genericType) + { + if (genericType.GenericArguments.Any(this.IsMatch)) + return true; + } + + // generic parameters (e.g. constraints) + if (type.GenericParameters.Any(this.IsMatch)) + return true; + + return false; + } } }