summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs30
-rw-r--r--src/SMAPI/Framework/ModLoading/RewriteHelper.cs43
2 files changed, 39 insertions, 34 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
index 47c8b33c..cf5a3175 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
-using System.Text.RegularExpressions;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -16,9 +15,6 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <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);
-
/*********
** Accessors
@@ -65,12 +61,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
return InstructionHandleResult.None;
// validate return type
- string actualReturnTypeID = this.GetComparableTypeID(targetField.FieldType);
- string expectedReturnTypeID = this.GetComparableTypeID(fieldRef.FieldType);
-
- if (!RewriteHelper.LooksLikeSameType(expectedReturnTypeID, actualReturnTypeID))
+ if (!RewriteHelper.LooksLikeSameType(fieldRef.FieldType, targetField.FieldType))
{
- this.NounPhrase = $"reference to {fieldRef.DeclaringType.FullName}.{fieldRef.Name} (field returns {this.GetFriendlyTypeName(targetField.FieldType, actualReturnTypeID)}, not {this.GetFriendlyTypeName(fieldRef.FieldType, expectedReturnTypeID)})";
+ this.NounPhrase = $"reference to {fieldRef.DeclaringType.FullName}.{fieldRef.Name} (field returns {this.GetFriendlyTypeName(targetField.FieldType)}, not {this.GetFriendlyTypeName(fieldRef.FieldType)})";
return InstructionHandleResult.NotCompatible;
}
}
@@ -92,10 +85,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
return InstructionHandleResult.NotCompatible;
}
- string expectedReturnType = this.GetComparableTypeID(methodDef.ReturnType);
- if (candidateMethods.All(method => !RewriteHelper.LooksLikeSameType(this.GetComparableTypeID(method.ReturnType), expectedReturnType)))
+ if (candidateMethods.All(method => !RewriteHelper.LooksLikeSameType(method.ReturnType, methodDef.ReturnType)))
{
- this.NounPhrase = $"reference to {methodDef.DeclaringType.FullName}.{methodDef.Name} (no such method returns {this.GetFriendlyTypeName(methodDef.ReturnType, expectedReturnType)})";
+ this.NounPhrase = $"reference to {methodDef.DeclaringType.FullName}.{methodDef.Name} (no such method returns {this.GetFriendlyTypeName(methodDef.ReturnType)})";
return InstructionHandleResult.NotCompatible;
}
}
@@ -114,17 +106,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
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)
- {
- return this.StripTypeNamePattern.Replace(type.FullName, "");
- }
-
/// <summary>Get a shorter type name for display.</summary>
/// <param name="type">The type reference.</param>
- /// <param name="typeID">The comparable type ID from <see cref="GetComparableTypeID"/>.</param>
- private string GetFriendlyTypeName(TypeReference type, string typeID)
+ private string GetFriendlyTypeName(TypeReference type)
{
// most common built-in types
switch (type.FullName)
@@ -141,10 +125,10 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
foreach (string @namespace in new[] { "Microsoft.Xna.Framework", "Netcode", "System", "System.Collections.Generic" })
{
if (type.Namespace == @namespace)
- return typeID.Substring(@namespace.Length + 1);
+ return type.Name;
}
- return typeID;
+ return type.FullName;
}
}
}
diff --git a/src/SMAPI/Framework/ModLoading/RewriteHelper.cs b/src/SMAPI/Framework/ModLoading/RewriteHelper.cs
index 1600069d..f8684cde 100644
--- a/src/SMAPI/Framework/ModLoading/RewriteHelper.cs
+++ b/src/SMAPI/Framework/ModLoading/RewriteHelper.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using System.Text.RegularExpressions;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -11,6 +12,13 @@ namespace StardewModdingAPI.Framework.ModLoading
internal static class RewriteHelper
{
/*********
+ ** Properties
+ *********/
+ /// <summary>A pattern matching type name substrings to strip for display.</summary>
+ private static readonly Regex StripTypeNamePattern = new Regex(@"`\d+(?=<)", RegexOptions.Compiled);
+
+
+ /*********
** Public methods
*********/
/// <summary>Get the field reference from an instruction if it matches.</summary>
@@ -109,29 +117,39 @@ namespace StardewModdingAPI.Framework.ModLoading
}
/// <summary>Determine whether two type IDs look like the same type, accounting for placeholder values such as !0.</summary>
- /// <param name="typeA">The type ID to compare.</param>
- /// <param name="typeB">The other type ID to compare.</param>
+ /// <param name="a">The type ID to compare.</param>
+ /// <param name="b">The other type ID to compare.</param>
/// <returns>true if the type IDs look like the same type, false if not.</returns>
- public static bool LooksLikeSameType(string typeA, string typeB)
+ public static bool LooksLikeSameType(TypeReference a, TypeReference b)
{
+ string typeA = RewriteHelper.GetComparableTypeID(a);
+ string typeB = RewriteHelper.GetComparableTypeID(b);
+
string placeholderType = "", actualType = "";
if (RewriteHelper.HasPlaceholder(typeA))
{
placeholderType = typeA;
actualType = typeB;
- } else if (RewriteHelper.HasPlaceholder(typeB))
+ }
+ else if (RewriteHelper.HasPlaceholder(typeB))
{
placeholderType = typeB;
actualType = typeA;
- } else
- {
- return typeA == typeB;
}
+ else
+ return typeA == typeB;
return RewriteHelper.PlaceholderTypeValidates(placeholderType, actualType);
}
+ /// <summary>Get a unique string representation of a type.</summary>
+ /// <param name="type">The type reference.</param>
+ private static string GetComparableTypeID(TypeReference type)
+ {
+ return RewriteHelper.StripTypeNamePattern.Replace(type.FullName, "");
+ }
+
protected class SymbolLocation
{
public string symbol;
@@ -144,7 +162,7 @@ namespace StardewModdingAPI.Framework.ModLoading
}
}
- private static List<char> symbolBoundaries = new List<char>{'<', '>', ','};
+ private static List<char> symbolBoundaries = new List<char> { '<', '>', ',' };
/// <summary> Traverses and parses out symbols from a type which does not contain placeholder values.</summary>
/// <param name="type">The type to traverse.</param>
@@ -160,7 +178,8 @@ namespace StardewModdingAPI.Framework.ModLoading
{
typeSymbols.Add(new SymbolLocation(symbol, depth));
symbol = "";
- switch (c) {
+ switch (c)
+ {
case '<':
depth++;
break;
@@ -186,7 +205,8 @@ namespace StardewModdingAPI.Framework.ModLoading
if (symbolA.depth != symbolB.depth)
return false;
- if (!RewriteHelper.IsPlaceholder(symbolA.symbol)) {
+ if (!RewriteHelper.IsPlaceholder(symbolA.symbol))
+ {
return symbolA.symbol == symbolB.symbol;
}
@@ -245,7 +265,8 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="placeholderType">The type with placeholders in it.</param>
/// <param name="actualType">The type without placeholders.</param>
/// <returns>true if the placeholder type can resolve to the actual type, false if not.</returns>
- private static bool PlaceholderTypeValidates(string placeholderType, string actualType) {
+ private static bool PlaceholderTypeValidates(string placeholderType, string actualType)
+ {
List<SymbolLocation> typeSymbols = new List<SymbolLocation>();
RewriteHelper.TraverseActualType(actualType, typeSymbols);