fix type finder not matching generic type parameters (#254)

This commit is contained in:
Jesse Plamondon-Willard 2017-03-26 19:21:24 -04:00
parent 8bf3ef118a
commit 911957d582
1 changed files with 29 additions and 9 deletions

View File

@ -72,12 +72,12 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
/// <param name="method">The method deifnition.</param> /// <param name="method">The method deifnition.</param>
protected bool IsMatch(MethodDefinition method) protected bool IsMatch(MethodDefinition method)
{ {
if (method.ReturnType.FullName == this.FullTypeName) if (this.IsMatch(method.ReturnType))
return true; return true;
foreach (VariableDefinition variable in method.Body.Variables) foreach (VariableDefinition variable in method.Body.Variables)
{ {
if (variable.VariableType.FullName == this.FullTypeName) if (this.IsMatch(variable.VariableType))
return true; return true;
} }
@ -88,15 +88,13 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
/// <param name="instruction">The IL instruction.</param> /// <param name="instruction">The IL instruction.</param>
protected bool IsMatch(Instruction instruction) protected bool IsMatch(Instruction instruction)
{ {
string fullName = this.FullTypeName;
// field reference // field reference
FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction);
if (fieldRef != null) if (fieldRef != null)
{ {
return return
fieldRef.DeclaringType.FullName == fullName // field on target class this.IsMatch(fieldRef.DeclaringType) // field on target class
|| fieldRef.FieldType.FullName == fullName; // field value is target class || this.IsMatch(fieldRef.FieldType); // field value is target class
} }
// method reference // method reference
@ -104,12 +102,34 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders
if (methodRef != null) if (methodRef != null)
{ {
return return
methodRef.DeclaringType.FullName == fullName // method on target class this.IsMatch(methodRef.DeclaringType) // method on target class
|| methodRef.ReturnType.FullName == fullName // method returns target class || this.IsMatch(methodRef.ReturnType) // method returns target class
|| methodRef.Parameters.Any(p => p.ParameterType.FullName == fullName); // method parameters || methodRef.Parameters.Any(p => this.IsMatch(p.ParameterType)); // method parameters
} }
return false; return false;
} }
/// <summary>Get whether a type reference matches the expected type.</summary>
/// <param name="type">The type to check.</param>
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;
}
} }
} }