From 771263299cae11d464c25c5291e59507c639e822 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 3 Jul 2017 01:03:13 -0400 Subject: add SMAPI 2.0 compile mode --- .../Finders/PropertyFinder.cs | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/StardewModdingAPI.AssemblyRewriters/Finders/PropertyFinder.cs (limited to 'src/StardewModdingAPI.AssemblyRewriters/Finders') diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/PropertyFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/PropertyFinder.cs new file mode 100644 index 00000000..441f15f2 --- /dev/null +++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/PropertyFinder.cs @@ -0,0 +1,83 @@ +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace StardewModdingAPI.AssemblyRewriters.Finders +{ + /// Finds incompatible CIL instructions that reference a given property and throws an . + public class PropertyFinder : IInstructionRewriter + { + /********* + ** Properties + *********/ + /// The full type name for which to find references. + private readonly string FullTypeName; + + /// The property name for which to find references. + private readonly string PropertyName; + + + /********* + ** Accessors + *********/ + /// A brief noun phrase indicating what the instruction finder matches. + public string NounPhrase { get; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The full type name for which to find references. + /// The property name for which to find references. + /// A brief noun phrase indicating what the instruction finder matches (or null to generate one). + public PropertyFinder(string fullTypeName, string propertyName, string nounPhrase = null) + { + this.FullTypeName = fullTypeName; + this.PropertyName = propertyName; + this.NounPhrase = nounPhrase ?? $"{fullTypeName}.{propertyName} property"; + } + + /// Rewrite a method definition for compatibility. + /// The module being rewritten. + /// The method definition to rewrite. + /// Metadata for mapping assemblies to the current platform. + /// Whether the mod was compiled on a different platform. + /// Returns whether the instruction was rewritten. + /// The CIL instruction is not compatible, and can't be rewritten. + public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged) + { + return false; + } + + /// Rewrite a CIL instruction for compatibility. + /// The module being rewritten. + /// The CIL rewriter. + /// The instruction to rewrite. + /// Metadata for mapping assemblies to the current platform. + /// Whether the mod was compiled on a different platform. + /// Returns whether the instruction was rewritten. + /// The CIL instruction is not compatible, and can't be rewritten. + public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged) + { + if (!this.IsMatch(instruction)) + return false; + + throw new IncompatibleInstructionException(this.NounPhrase); + } + + + /********* + ** Protected methods + *********/ + /// Get whether a CIL instruction matches. + /// The IL instruction. + protected bool IsMatch(Instruction instruction) + { + MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); + return + methodRef != null + && methodRef.DeclaringType.FullName == this.FullTypeName + && (methodRef.Name == "get_" + this.PropertyName || methodRef.Name == "set_" + this.PropertyName); + } + } +} -- cgit