summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ModLoading/Finders
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-03-05 19:07:22 -0500
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-03-05 19:07:22 -0500
commit8689fe65642d07fa6a2513aa36c1389479e50d0c (patch)
tree65e2055edc73c354b1995bcae96c5339fbd61e5c /src/SMAPI/Framework/ModLoading/Finders
parent1fbd41ecb2141d769072c71822fb02876401a592 (diff)
downloadSMAPI-8689fe65642d07fa6a2513aa36c1389479e50d0c.tar.gz
SMAPI-8689fe65642d07fa6a2513aa36c1389479e50d0c.tar.bz2
SMAPI-8689fe65642d07fa6a2513aa36c1389479e50d0c.zip
fix compatibility heuristics incorrectly flagging mods with missing optional references (#453)
Diffstat (limited to 'src/SMAPI/Framework/ModLoading/Finders')
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs22
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs26
2 files changed, 44 insertions, 4 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
index 0e7344a8..b5e45742 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Mono.Cecil;
@@ -12,6 +13,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/*********
** Properties
*********/
+ /// <summary>The assembly names to which to heuristically detect broken references.</summary>
+ private readonly HashSet<string> ValidateReferencesToAssemblies;
+
/// <summary>A pattern matching type name substrings to strip for display.</summary>
private readonly Regex StripTypeNamePattern = new Regex(@"`\d+(?=<)", RegexOptions.Compiled);
@@ -26,6 +30,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/*********
** Public methods
*********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="validateReferencesToAssemblies">The assembly names to which to heuristically detect broken references.</param>
+ public ReferenceToMemberWithUnexpectedTypeFinder(string[] validateReferencesToAssemblies)
+ {
+ 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>
@@ -46,7 +57,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
{
// field reference
FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction);
- if (fieldRef != null)
+ if (fieldRef != null && this.ShouldValidate(fieldRef.DeclaringType))
{
// can't compare generic type parameters between definition and reference
if (fieldRef.FieldType.IsGenericInstance || fieldRef.FieldType.IsGenericParameter)
@@ -69,7 +80,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
// method reference
MethodReference methodReference = RewriteHelper.AsMethodReference(instruction);
- if (methodReference != null)
+ if (methodReference != null && this.ShouldValidate(methodReference.DeclaringType))
{
// can't compare generic type parameters between definition and reference
if (methodReference.ReturnType.IsGenericInstance || methodReference.ReturnType.IsGenericParameter)
@@ -103,6 +114,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/*********
** Private methods
*********/
+ /// <summary>Whether references to the given type should be validated.</summary>
+ /// <param name="type">The type reference.</param>
+ private bool ShouldValidate(TypeReference type)
+ {
+ return type != null && this.ValidateReferencesToAssemblies.Contains(type.Scope.Name);
+ }
+
/// <summary>Get a unique string representation of a type.</summary>
/// <param name="type">The type reference.</param>
private string GetComparableTypeID(TypeReference type)
diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
index 60373c9d..f5e33313 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -9,6 +10,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
internal class ReferenceToMissingMemberFinder : IInstructionHandler
{
/*********
+ ** Properties
+ *********/
+ /// <summary>The assembly names to which to heuristically detect broken references.</summary>
+ private readonly HashSet<string> ValidateReferencesToAssemblies;
+
+
+ /*********
** Accessors
*********/
/// <summary>A brief noun phrase indicating what the instruction finder matches.</summary>
@@ -18,6 +26,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/*********
** 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)
+ {
+ 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>
@@ -38,7 +53,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
{
// field reference
FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction);
- if (fieldRef != null)
+ if (fieldRef != null && this.ShouldValidate(fieldRef.DeclaringType))
{
FieldDefinition target = fieldRef.DeclaringType.Resolve()?.Fields.FirstOrDefault(p => p.Name == fieldRef.Name);
if (target == null)
@@ -50,7 +65,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
// method reference
MethodReference methodRef = RewriteHelper.AsMethodReference(instruction);
- if (methodRef != null && !this.IsUnsupported(methodRef))
+ if (methodRef != null && this.ShouldValidate(methodRef.DeclaringType) && !this.IsUnsupported(methodRef))
{
MethodDefinition target = methodRef.DeclaringType.Resolve()?.Methods.FirstOrDefault(p => p.Name == methodRef.Name);
if (target == null)
@@ -69,6 +84,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/*********
** Private methods
*********/
+ /// <summary>Whether references to the given type should be validated.</summary>
+ /// <param name="type">The type reference.</param>
+ private bool ShouldValidate(TypeReference type)
+ {
+ return type != null && this.ValidateReferencesToAssemblies.Contains(type.Scope.Name);
+ }
+
/// <summary>Get whether a method reference is a special case that's not currently supported (e.g. array methods).</summary>
/// <param name="method">The method reference.</param>
private bool IsUnsupported(MethodReference method)