diff options
-rw-r--r-- | src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs | 10 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs | 18 | ||||
-rw-r--r-- | src/SMAPI/Metadata/InstructionMetadata.cs | 8 |
3 files changed, 19 insertions, 17 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs index 45349def..79045241 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/TypeFinder.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; @@ -16,6 +17,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders /// <summary>The result to return for matching instructions.</summary> private readonly InstructionHandleResult Result; + /// <summary>A lambda which overrides a matched type.</summary> + protected readonly Func<TypeReference, bool> ShouldIgnore; + /********* ** Accessors @@ -30,11 +34,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders /// <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> - public TypeFinder(string fullTypeName, InstructionHandleResult result) + /// <param name="shouldIgnore">A lambda which overrides a matched type.</param> + public TypeFinder(string fullTypeName, InstructionHandleResult result, Func<TypeReference, bool> shouldIgnore = null) { this.FullTypeName = fullTypeName; this.Result = result; this.NounPhrase = $"{fullTypeName} type"; + this.ShouldIgnore = shouldIgnore ?? (p => false); } /// <summary>Perform the predefined logic for a method if applicable.</summary> @@ -113,7 +119,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders protected bool IsMatch(TypeReference type) { // root type - if (type.FullName == this.FullTypeName) + if (type.FullName == this.FullTypeName && !this.ShouldIgnore(type)) return true; // generic arguments diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs index de9c439a..1bef4df4 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs @@ -17,9 +17,6 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// <summary>The new type to reference.</summary> private readonly Type ToType; - /// <summary>A lambda which indicates whether a matching type reference should be rewritten.</summary> - private readonly Func<TypeReference, bool> ShouldRewrite; - /********* ** Public methods @@ -27,13 +24,12 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// <summary>Construct an instance.</summary> /// <param name="fromTypeFullName">The full type name to which to find references.</param> /// <param name="toType">The new type to reference.</param> - /// <param name="shouldRewrite">A lambda which indicates whether a matching type reference should be rewritten.</param> - public TypeReferenceRewriter(string fromTypeFullName, Type toType, Func<TypeReference, bool> shouldRewrite = null) - : base(fromTypeFullName, InstructionHandleResult.None) + /// <param name="shouldIgnore">A lambda which overrides a matched type.</param> + public TypeReferenceRewriter(string fromTypeFullName, Type toType, Func<TypeReference, bool> shouldIgnore = null) + : base(fromTypeFullName, InstructionHandleResult.None, shouldIgnore) { this.FromTypeName = fromTypeFullName; this.ToType = toType; - this.ShouldRewrite = shouldRewrite ?? (type => true); } /// <summary>Perform the predefined logic for a method if applicable.</summary> @@ -138,22 +134,22 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// <param name="type">The type to replace if it matches.</param> private TypeReference RewriteIfNeeded(ModuleDefinition module, TypeReference type) { - // root type + // current type if (type.FullName == this.FromTypeName) { - if (!this.ShouldRewrite(type)) + if (this.ShouldIgnore(type)) return type; return module.ImportReference(this.ToType); } - // generic arguments + // recurse into generic arguments if (type is GenericInstanceType genericType) { for (int i = 0; i < genericType.GenericArguments.Count; i++) genericType.GenericArguments[i] = this.RewriteIfNeeded(module, genericType.GenericArguments[i]); } - // generic parameters (e.g. constraints) + // recurse into generic parameters (e.g. constraints) for (int i = 0; i < type.GenericParameters.Count; i++) type.GenericParameters[i] = new GenericParameter(this.RewriteIfNeeded(module, type.GenericParameters[i])); diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index c5128eb1..aa3e743c 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -38,10 +38,10 @@ namespace StardewModdingAPI.Metadata new VirtualEntryCallRemover(), // rewrite for SMAPI 2.6 (types moved into SMAPI.Toolkit.CoreInterfaces) - new TypeReferenceRewriter("StardewModdingAPI.IManifest", typeof(IManifest), type => type.Scope.Name == "StardewModdingAPI"), - new TypeReferenceRewriter("StardewModdingAPI.IManifestContentPackFor", typeof(IManifestContentPackFor), type => type.Scope.Name == "StardewModdingAPI"), - new TypeReferenceRewriter("StardewModdingAPI.IManifestDependency", typeof(IManifestDependency), type => type.Scope.Name == "StardewModdingAPI"), - new TypeReferenceRewriter("StardewModdingAPI.ISemanticVersion", typeof(ISemanticVersion), type => type.Scope.Name == "StardewModdingAPI"), + new TypeReferenceRewriter("StardewModdingAPI.IManifest", typeof(IManifest), shouldIgnore: type => type.Scope.Name != "StardewModdingAPI"), + new TypeReferenceRewriter("StardewModdingAPI.IManifestContentPackFor", typeof(IManifestContentPackFor), shouldIgnore: type => type.Scope.Name != "StardewModdingAPI"), + new TypeReferenceRewriter("StardewModdingAPI.IManifestDependency", typeof(IManifestDependency), shouldIgnore: type => type.Scope.Name != "StardewModdingAPI"), + new TypeReferenceRewriter("StardewModdingAPI.ISemanticVersion", typeof(ISemanticVersion), shouldIgnore: type => type.Scope.Name != "StardewModdingAPI"), // rewrite for Stardew Valley 1.3 new StaticFieldToConstantRewriter<int>(typeof(Game1), "tileSize", Game1.tileSize), |