pass mod metadata into rewriters (#347)

This commit is contained in:
Jesse Plamondon-Willard 2017-09-19 22:52:52 -04:00
parent 954de8c4f2
commit c513bb011c
12 changed files with 45 additions and 25 deletions

View File

@ -53,11 +53,12 @@ namespace StardewModdingAPI.Framework.ModLoading
}
/// <summary>Preprocess and load an assembly.</summary>
/// <param name="mod">The mod for which the assembly is being loaded.</param>
/// <param name="assemblyPath">The assembly file path.</param>
/// <param name="assumeCompatible">Assume the mod is compatible, even if incompatible code is detected.</param>
/// <returns>Returns the rewrite metadata for the preprocessed assembly.</returns>
/// <exception cref="IncompatibleInstructionException">An incompatible CIL instruction was found while rewriting the assembly.</exception>
public Assembly Load(string assemblyPath, bool assumeCompatible)
public Assembly Load(IModMetadata mod, string assemblyPath, bool assumeCompatible)
{
// get referenced local assemblies
AssemblyParseResult[] assemblies;
@ -86,7 +87,7 @@ namespace StardewModdingAPI.Framework.ModLoading
if (assembly.Status == AssemblyLoadStatus.AlreadyLoaded)
continue;
bool changed = this.RewriteAssembly(assembly.Definition, assumeCompatible, logPrefix: " ");
bool changed = this.RewriteAssembly(mod, assembly.Definition, assumeCompatible, logPrefix: " ");
if (changed)
{
if (!oneAssembly)
@ -173,12 +174,13 @@ namespace StardewModdingAPI.Framework.ModLoading
** Assembly rewriting
****/
/// <summary>Rewrite the types referenced by an assembly.</summary>
/// <param name="mod">The mod for which the assembly is being loaded.</param>
/// <param name="assembly">The assembly to rewrite.</param>
/// <param name="assumeCompatible">Assume the mod is compatible, even if incompatible code is detected.</param>
/// <param name="logPrefix">A string to prefix to log messages.</param>
/// <returns>Returns whether the assembly was modified.</returns>
/// <exception cref="IncompatibleInstructionException">An incompatible CIL instruction was found while rewriting the assembly.</exception>
private bool RewriteAssembly(AssemblyDefinition assembly, bool assumeCompatible, string logPrefix)
private bool RewriteAssembly(IModMetadata mod, AssemblyDefinition assembly, bool assumeCompatible, string logPrefix)
{
ModuleDefinition module = assembly.MainModule;
HashSet<string> loggedMessages = new HashSet<string>();
@ -211,7 +213,7 @@ namespace StardewModdingAPI.Framework.ModLoading
// find (and optionally rewrite) incompatible instructions
bool anyRewritten = false;
IInstructionRewriter[] rewriters = Constants.GetRewriters().ToArray();
IInstructionRewriter[] rewriters = Constants.GetRewriters(this.Monitor).ToArray();
foreach (MethodDefinition method in this.GetMethods(module))
{
// check method definition
@ -219,7 +221,7 @@ namespace StardewModdingAPI.Framework.ModLoading
{
try
{
if (rewriter.Rewrite(module, method, this.AssemblyMap, platformChanged))
if (rewriter.Rewrite(mod, module, method, this.AssemblyMap, platformChanged))
{
this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Rewrote {filename} to fix {rewriter.NounPhrase}...");
anyRewritten = true;
@ -241,7 +243,7 @@ namespace StardewModdingAPI.Framework.ModLoading
{
try
{
if (rewriter.Rewrite(module, cil, instruction, this.AssemblyMap, platformChanged))
if (rewriter.Rewrite(mod, module, cil, instruction, this.AssemblyMap, platformChanged))
{
this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Rewrote {filename} to fix {rewriter.NounPhrase}...");
anyRewritten = true;

View File

@ -38,18 +38,20 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
}
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
return false;
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -57,7 +59,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return false;

View File

@ -38,18 +38,20 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
}
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
return false;
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -57,7 +59,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return false;

View File

@ -38,18 +38,20 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
}
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
return false;
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -57,7 +59,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return false;

View File

@ -38,18 +38,20 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
}
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
return false;
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -57,7 +59,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return false;

View File

@ -34,13 +34,14 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
}
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(method))
return false;
@ -49,6 +50,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -56,7 +58,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public virtual bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public virtual bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return false;

View File

@ -17,15 +17,17 @@ namespace StardewModdingAPI.Framework.ModLoading
** Methods
*********/
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged);
bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged);
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -33,6 +35,6 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged);
bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged);
}
}

View File

@ -33,6 +33,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -40,7 +41,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public override bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public override bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return false;

View File

@ -33,6 +33,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -40,7 +41,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public override bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public override bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return false;

View File

@ -44,18 +44,20 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
}
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
public bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
return false;
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -63,7 +65,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction, platformChanged))
return false;

View File

@ -33,13 +33,14 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
}
/// <summary>Rewrite a method definition for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="method">The method definition to rewrite.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public override bool Rewrite(ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
public override bool Rewrite(IModMetadata mod, ModuleDefinition module, MethodDefinition method, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
bool rewritten = false;
@ -87,6 +88,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
}
/// <summary>Rewrite a CIL instruction for compatibility.</summary>
/// <param name="mod">The mod to which the module belongs.</param>
/// <param name="module">The module being rewritten.</param>
/// <param name="cil">The CIL rewriter.</param>
/// <param name="instruction">The instruction to rewrite.</param>
@ -94,7 +96,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
/// <returns>Returns whether the instruction was rewritten.</returns>
/// <exception cref="IncompatibleInstructionException">The CIL instruction is not compatible, and can't be rewritten.</exception>
public override bool Rewrite(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
public override bool Rewrite(IModMetadata mod, ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction) && !instruction.ToString().Contains(this.FromTypeName))
return false;

View File

@ -645,7 +645,7 @@ namespace StardewModdingAPI
Assembly modAssembly;
try
{
modAssembly = modAssemblyLoader.Load(assemblyPath, assumeCompatible: metadata.Compatibility?.Compatibility == ModCompatibilityType.AssumeCompatible);
modAssembly = modAssemblyLoader.Load(metadata, assemblyPath, assumeCompatible: metadata.Compatibility?.Compatibility == ModCompatibilityType.AssumeCompatible);
}
catch (IncompatibleInstructionException ex)
{