From 8bf3ef118a822afd1c7d7f80f6cf6eaeed346167 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 26 Mar 2017 19:17:48 -0400 Subject: add support for rewriting method definitions (#254) --- .../Finders/EventFinder.cs | 19 +++++++++--- .../Finders/FieldFinder.cs | 17 ++++++++-- .../Finders/MethodFinder.cs | 17 ++++++++-- .../Finders/TypeFinder.cs | 36 ++++++++++++++++++++-- 4 files changed, 76 insertions(+), 13 deletions(-) (limited to 'src/StardewModdingAPI.AssemblyRewriters/Finders') diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs index bcceee32..c0051469 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs +++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/EventFinder.cs @@ -37,6 +37,18 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders this.NounPhrase = nounPhrase ?? $"{fullTypeName}.{eventName} event"; } + /// 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. @@ -45,9 +57,9 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders /// 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 bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged) + public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged) { - if (!this.IsMatch(instruction, platformChanged)) + if (!this.IsMatch(instruction)) return false; throw new IncompatibleInstructionException(this.NounPhrase); @@ -59,8 +71,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders *********/ /// Get whether a CIL instruction matches. /// The IL instruction. - /// Whether the mod was compiled on a different platform. - protected bool IsMatch(Instruction instruction, bool platformChanged) + protected bool IsMatch(Instruction instruction) { MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); return diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs index cdfc3bd5..b44883e9 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs +++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/FieldFinder.cs @@ -37,6 +37,18 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders this.NounPhrase = nounPhrase ?? $"{fullTypeName}.{fieldName} field"; } + /// 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. @@ -47,7 +59,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders /// 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, platformChanged)) + if (!this.IsMatch(instruction)) return false; throw new IncompatibleInstructionException(this.NounPhrase); @@ -59,8 +71,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders *********/ /// Get whether a CIL instruction matches. /// The IL instruction. - /// Whether the mod was compiled on a different platform. - protected bool IsMatch(Instruction instruction, bool platformChanged) + protected bool IsMatch(Instruction instruction) { FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); return diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs index 2efcbb0f..19dda58a 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs +++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/MethodFinder.cs @@ -37,6 +37,18 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders this.NounPhrase = nounPhrase ?? $"{fullTypeName}.{methodName} method"; } + /// 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. @@ -47,7 +59,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders /// The CIL instruction is not compatible, and can't be rewritten. public bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged) { - if (!this.IsMatch(instruction, platformChanged)) + if (!this.IsMatch(instruction)) return false; throw new IncompatibleInstructionException(this.NounPhrase); @@ -59,8 +71,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders *********/ /// Get whether a CIL instruction matches. /// The IL instruction. - /// Whether the mod was compiled on a different platform. - protected bool IsMatch(Instruction instruction, bool platformChanged) + protected bool IsMatch(Instruction instruction) { MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); return diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs index 96cbb229..0e4d6824 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs +++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/TypeFinder.cs @@ -33,6 +33,21 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders this.NounPhrase = nounPhrase ?? $"{fullTypeName} type"; } + /// 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) + { + if (!this.IsMatch(method)) + return false; + + throw new IncompatibleInstructionException(this.NounPhrase); + } + /// Rewrite a CIL instruction for compatibility. /// The module being rewritten. /// The CIL rewriter. @@ -43,7 +58,7 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders /// 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, platformChanged)) + if (!this.IsMatch(instruction)) return false; throw new IncompatibleInstructionException(this.NounPhrase); @@ -53,10 +68,25 @@ namespace StardewModdingAPI.AssemblyRewriters.Finders /********* ** Protected methods *********/ + /// Get whether a CIL instruction matches. + /// The method deifnition. + protected bool IsMatch(MethodDefinition method) + { + if (method.ReturnType.FullName == this.FullTypeName) + return true; + + foreach (VariableDefinition variable in method.Body.Variables) + { + if (variable.VariableType.FullName == this.FullTypeName) + return true; + } + + return false; + } + /// Get whether a CIL instruction matches. /// The IL instruction. - /// Whether the mod was compiled on a different platform. - protected bool IsMatch(Instruction instruction, bool platformChanged) + protected bool IsMatch(Instruction instruction) { string fullName = this.FullTypeName; -- cgit