summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs')
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs49
1 files changed, 19 insertions, 30 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
index 44b531a5..ebb62948 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
@@ -1,13 +1,15 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
+using StardewModdingAPI.Framework.ModLoading.Framework;
namespace StardewModdingAPI.Framework.ModLoading.Finders
{
/// <summary>Finds references to a field, property, or method which no longer exists.</summary>
/// <remarks>This implementation is purely heuristic. It should never return a false positive, but won't detect all cases.</remarks>
- internal class ReferenceToMissingMemberFinder : IInstructionHandler
+ internal class ReferenceToMissingMemberFinder : BaseInstructionHandler
{
/*********
** Fields
@@ -17,39 +19,23 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/*********
- ** Accessors
- *********/
- /// <summary>A brief noun phrase indicating what the instruction finder matches.</summary>
- public string NounPhrase { get; private set; } = "";
-
-
- /*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="validateReferencesToAssemblies">The assembly names to which to heuristically detect broken references.</param>
public ReferenceToMissingMemberFinder(string[] validateReferencesToAssemblies)
+ : base(defaultPhrase: "")
{
this.ValidateReferencesToAssemblies = new HashSet<string>(validateReferencesToAssemblies);
}
- /// <summary>Perform the predefined logic for a method if applicable.</summary>
- /// <param name="module">The assembly module containing the instruction.</param>
- /// <param name="method">The method definition containing the instruction.</param>
- /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
- /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
- public virtual InstructionHandleResult Handle(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
- {
- return InstructionHandleResult.None;
- }
-
- /// <summary>Perform the predefined logic for an instruction if applicable.</summary>
+ /// <summary>Rewrite a CIL instruction reference if needed.</summary>
/// <param name="module">The assembly module containing the instruction.</param>
/// <param name="cil">The CIL processor.</param>
- /// <param name="instruction">The instruction to handle.</param>
- /// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
- /// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
- public virtual InstructionHandleResult Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
+ /// <param name="instruction">The CIL instruction to handle.</param>
+ /// <param name="replaceWith">Replaces the CIL instruction with a new one.</param>
+ /// <returns>Returns whether the instruction was changed.</returns>
+ public override bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction, Action<Instruction> replaceWith)
{
// field reference
FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction);
@@ -58,8 +44,8 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
FieldDefinition target = fieldRef.DeclaringType.Resolve()?.Fields.FirstOrDefault(p => p.Name == fieldRef.Name);
if (target == null)
{
- this.NounPhrase = $"reference to {fieldRef.DeclaringType.FullName}.{fieldRef.Name} (no such field)";
- return InstructionHandleResult.NotCompatible;
+ this.MarkFlag(InstructionHandleResult.NotCompatible, $"reference to {fieldRef.DeclaringType.FullName}.{fieldRef.Name} (no such field)");
+ return false;
}
}
@@ -70,17 +56,20 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
MethodDefinition target = methodRef.Resolve();
if (target == null)
{
+ string phrase = null;
if (this.IsProperty(methodRef))
- this.NounPhrase = $"reference to {methodRef.DeclaringType.FullName}.{methodRef.Name.Substring(4)} (no such property)";
+ phrase = $"reference to {methodRef.DeclaringType.FullName}.{methodRef.Name.Substring(4)} (no such property)";
else if (methodRef.Name == ".ctor")
- this.NounPhrase = $"reference to {methodRef.DeclaringType.FullName}.{methodRef.Name} (no matching constructor)";
+ phrase = $"reference to {methodRef.DeclaringType.FullName}.{methodRef.Name} (no matching constructor)";
else
- this.NounPhrase = $"reference to {methodRef.DeclaringType.FullName}.{methodRef.Name} (no such method)";
- return InstructionHandleResult.NotCompatible;
+ phrase = $"reference to {methodRef.DeclaringType.FullName}.{methodRef.Name} (no such method)";
+
+ this.MarkFlag(InstructionHandleResult.NotCompatible, phrase);
+ return false;
}
}
- return InstructionHandleResult.None;
+ return false;
}