summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ModLoading/Finders
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/ModLoading/Finders')
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs57
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs34
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs6
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs6
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs27
5 files changed, 86 insertions, 44 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs
index 01ed153b..a2ea3232 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs
@@ -1,3 +1,5 @@
+using System.Collections.Generic;
+using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using StardewModdingAPI.Framework.ModLoading.Framework;
@@ -13,8 +15,8 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <summary>The full type name for which to find references.</summary>
private readonly string FullTypeName;
- /// <summary>The event name for which to find references.</summary>
- private readonly string EventName;
+ /// <summary>The method names for which to find references.</summary>
+ private readonly ISet<string> MethodNames;
/// <summary>The result to return for matching instructions.</summary>
private readonly InstructionHandleResult Result;
@@ -25,38 +27,47 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
*********/
/// <summary>Construct an instance.</summary>
/// <param name="fullTypeName">The full type name for which to find references.</param>
- /// <param name="eventName">The event name for which to find references.</param>
+ /// <param name="eventNames">The event names for which to find references.</param>
/// <param name="result">The result to return for matching instructions.</param>
- public EventFinder(string fullTypeName, string eventName, InstructionHandleResult result)
- : base(defaultPhrase: $"{fullTypeName}.{eventName} event")
+ public EventFinder(string fullTypeName, string[] eventNames, InstructionHandleResult result)
+ : base(defaultPhrase: $"{string.Join(", ", eventNames.Select(p => $"{fullTypeName}.{p}"))} event{(eventNames.Length != 1 ? "s" : "")}") // default phrase should never be used
{
this.FullTypeName = fullTypeName;
- this.EventName = eventName;
this.Result = result;
+
+ this.MethodNames = new HashSet<string>();
+ foreach (string name in eventNames)
+ {
+ this.MethodNames.Add($"add_{name}");
+ this.MethodNames.Add($"remove_{name}");
+ }
}
+ /// <summary>Construct an instance.</summary>
+ /// <param name="fullTypeName">The full type name for which to find references.</param>
+ /// <param name="eventName">The event name for which to find references.</param>
+ /// <param name="result">The result to return for matching instructions.</param>
+ public EventFinder(string fullTypeName, string eventName, InstructionHandleResult result)
+ : this(fullTypeName, new[] { eventName }, result) { }
+
/// <inheritdoc />
public override bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction)
{
- if (!this.Flags.Contains(this.Result) && this.IsMatch(instruction))
- this.MarkFlag(this.Result);
-
- return false;
- }
+ if (this.MethodNames.Any())
+ {
+ MethodReference methodRef = RewriteHelper.AsMethodReference(instruction);
+ if (methodRef is not null && methodRef.DeclaringType.FullName == this.FullTypeName && this.MethodNames.Contains(methodRef.Name))
+ {
+ string eventName = methodRef.Name.Split(new[] { '_' }, 2)[1];
+ this.MethodNames.Remove($"add_{eventName}");
+ this.MethodNames.Remove($"remove_{eventName}");
+ this.MarkFlag(this.Result);
+ this.Phrases.Add($"{this.FullTypeName}.{eventName} event");
+ }
+ }
- /*********
- ** Protected methods
- *********/
- /// <summary>Get whether a CIL instruction matches.</summary>
- /// <param name="instruction">The IL instruction.</param>
- protected bool IsMatch(Instruction instruction)
- {
- MethodReference methodRef = RewriteHelper.AsMethodReference(instruction);
- return
- methodRef != null
- && methodRef.DeclaringType.FullName == this.FullTypeName
- && (methodRef.Name == "add_" + this.EventName || methodRef.Name == "remove_" + this.EventName);
+ return false;
}
}
}
diff --git a/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs
index 2c062243..0947062c 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs
@@ -1,3 +1,5 @@
+using System.Collections.Generic;
+using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using StardewModdingAPI.Framework.ModLoading.Framework;
@@ -13,8 +15,8 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <summary>The full type name for which to find references.</summary>
private readonly string FullTypeName;
- /// <summary>The field name for which to find references.</summary>
- private readonly string FieldName;
+ /// <summary>The field names for which to find references.</summary>
+ private readonly ISet<string> FieldNames;
/// <summary>The result to return for matching instructions.</summary>
private readonly InstructionHandleResult Result;
@@ -25,21 +27,37 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
*********/
/// <summary>Construct an instance.</summary>
/// <param name="fullTypeName">The full type name for which to find references.</param>
- /// <param name="fieldName">The field name for which to find references.</param>
+ /// <param name="fieldNames">The field names for which to find references.</param>
/// <param name="result">The result to return for matching instructions.</param>
- public FieldFinder(string fullTypeName, string fieldName, InstructionHandleResult result)
- : base(defaultPhrase: $"{fullTypeName}.{fieldName} field")
+ public FieldFinder(string fullTypeName, string[] fieldNames, InstructionHandleResult result)
+ : base(defaultPhrase: $"{string.Join(", ", fieldNames.Select(p => $"{fullTypeName}.{p}"))} field{(fieldNames.Length != 1 ? "s" : "")}") // default phrase should never be used
{
this.FullTypeName = fullTypeName;
- this.FieldName = fieldName;
+ this.FieldNames = new HashSet<string>(fieldNames);
this.Result = result;
}
+ /// <summary>Construct an instance.</summary>
+ /// <param name="fullTypeName">The full type name for which to find references.</param>
+ /// <param name="fieldName">The field name for which to find references.</param>
+ /// <param name="result">The result to return for matching instructions.</param>
+ public FieldFinder(string fullTypeName, string fieldName, InstructionHandleResult result)
+ : this(fullTypeName, new[] { fieldName }, result) { }
+
/// <inheritdoc />
public override bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction)
{
- if (!this.Flags.Contains(this.Result) && RewriteHelper.IsFieldReferenceTo(instruction, this.FullTypeName, this.FieldName))
- this.MarkFlag(this.Result);
+ if (this.FieldNames.Any())
+ {
+ FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction);
+ if (fieldRef is not null && fieldRef.DeclaringType.FullName == this.FullTypeName && this.FieldNames.Contains(fieldRef.Name))
+ {
+ this.FieldNames.Remove(fieldRef.Name);
+
+ this.MarkFlag(this.Result);
+ this.Phrases.Add($"{this.FullTypeName}.{fieldRef.Name} field");
+ }
+ }
return false;
}
diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
index b01a3240..8c1cae2b 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
@@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
** Fields
*********/
/// <summary>The assembly names to which to heuristically detect broken references.</summary>
- private readonly HashSet<string> ValidateReferencesToAssemblies;
+ private readonly ISet<string> ValidateReferencesToAssemblies;
/*********
@@ -22,10 +22,10 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
*********/
/// <summary>Construct an instance.</summary>
/// <param name="validateReferencesToAssemblies">The assembly names to which to heuristically detect broken references.</param>
- public ReferenceToMemberWithUnexpectedTypeFinder(string[] validateReferencesToAssemblies)
+ public ReferenceToMemberWithUnexpectedTypeFinder(ISet<string> validateReferencesToAssemblies)
: base(defaultPhrase: "")
{
- this.ValidateReferencesToAssemblies = new HashSet<string>(validateReferencesToAssemblies);
+ this.ValidateReferencesToAssemblies = validateReferencesToAssemblies;
}
/// <inheritdoc />
diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
index b64a255e..d305daf4 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
@@ -13,7 +13,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
** Fields
*********/
/// <summary>The assembly names to which to heuristically detect broken references.</summary>
- private readonly HashSet<string> ValidateReferencesToAssemblies;
+ private readonly ISet<string> ValidateReferencesToAssemblies;
/*********
@@ -21,10 +21,10 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
*********/
/// <summary>Construct an instance.</summary>
/// <param name="validateReferencesToAssemblies">The assembly names to which to heuristically detect broken references.</param>
- public ReferenceToMissingMemberFinder(string[] validateReferencesToAssemblies)
+ public ReferenceToMissingMemberFinder(ISet<string> validateReferencesToAssemblies)
: base(defaultPhrase: "")
{
- this.ValidateReferencesToAssemblies = new HashSet<string>(validateReferencesToAssemblies);
+ this.ValidateReferencesToAssemblies = validateReferencesToAssemblies;
}
/// <inheritdoc />
diff --git a/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs
index bbd081e8..260a8df8 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Mono.Cecil;
using StardewModdingAPI.Framework.ModLoading.Framework;
@@ -10,8 +11,8 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/*********
** Fields
*********/
- /// <summary>The full type name to match.</summary>
- private readonly string FullTypeName;
+ /// <summary>The full type names remaining to match.</summary>
+ private readonly ISet<string> FullTypeNames;
/// <summary>The result to return for matching instructions.</summary>
private readonly InstructionHandleResult Result;
@@ -24,22 +25,34 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
** Public methods
*********/
/// <summary>Construct an instance.</summary>
- /// <param name="fullTypeName">The full type name to match.</param>
+ /// <param name="fullTypeNames">The full type names to match.</param>
/// <param name="result">The result to return for matching instructions.</param>
/// <param name="shouldIgnore">Get whether a matched type should be ignored.</param>
- public TypeFinder(string fullTypeName, InstructionHandleResult result, Func<TypeReference, bool> shouldIgnore = null)
- : base(defaultPhrase: $"{fullTypeName} type")
+ public TypeFinder(string[] fullTypeNames, InstructionHandleResult result, Func<TypeReference, bool> shouldIgnore = null)
+ : base(defaultPhrase: $"{string.Join(", ", fullTypeNames)} type{(fullTypeNames.Length != 1 ? "s" : "")}") // default phrase should never be used
{
- this.FullTypeName = fullTypeName;
+ this.FullTypeNames = new HashSet<string>(fullTypeNames);
this.Result = result;
this.ShouldIgnore = shouldIgnore;
}
+ /// <summary>Construct an instance.</summary>
+ /// <param name="fullTypeName">The full type name to match.</param>
+ /// <param name="result">The result to return for matching instructions.</param>
+ /// <param name="shouldIgnore">Get whether a matched type should be ignored.</param>
+ public TypeFinder(string fullTypeName, InstructionHandleResult result, Func<TypeReference, bool> shouldIgnore = null)
+ : this(new[] { fullTypeName }, result, shouldIgnore) { }
+
/// <inheritdoc />
public override bool Handle(ModuleDefinition module, TypeReference type, Action<TypeReference> replaceWith)
{
- if (type.FullName == this.FullTypeName && this.ShouldIgnore?.Invoke(type) != true)
+ if (this.FullTypeNames.Contains(type.FullName) && this.ShouldIgnore?.Invoke(type) != true)
+ {
+ this.FullTypeNames.Remove(type.FullName);
+
this.MarkFlag(this.Result);
+ this.Phrases.Add($"{type.FullName} type");
+ }
return false;
}