summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs34
1 files changed, 20 insertions, 14 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs b/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs
index b304a732..9dc3680f 100644
--- a/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -58,8 +59,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
/// <returns>Returns whether the module was modified.</returns>
public bool RewriteModule()
{
- bool anyRewritten = false;
+ int typesChanged = 0;
Exception exception = null;
+
Parallel.ForEach(
source: this.Module.GetTypes().Where(type => type.BaseType != null), // skip special types like <Module>
body: type =>
@@ -67,33 +69,34 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
if (exception != null)
return;
+ bool changed = false;
try
{
- anyRewritten |= this.RewriteCustomAttributes(type.CustomAttributes);
- anyRewritten |= this.RewriteGenericParameters(type.GenericParameters);
+ changed |= this.RewriteCustomAttributes(type.CustomAttributes);
+ changed |= this.RewriteGenericParameters(type.GenericParameters);
foreach (InterfaceImplementation @interface in type.Interfaces)
- anyRewritten |= this.RewriteTypeReference(@interface.InterfaceType, newType => @interface.InterfaceType = newType);
+ changed |= this.RewriteTypeReference(@interface.InterfaceType, newType => @interface.InterfaceType = newType);
if (type.BaseType.FullName != "System.Object")
- anyRewritten |= this.RewriteTypeReference(type.BaseType, newType => type.BaseType = newType);
+ changed |= this.RewriteTypeReference(type.BaseType, newType => type.BaseType = newType);
foreach (MethodDefinition method in type.Methods)
{
- anyRewritten |= this.RewriteTypeReference(method.ReturnType, newType => method.ReturnType = newType);
- anyRewritten |= this.RewriteGenericParameters(method.GenericParameters);
- anyRewritten |= this.RewriteCustomAttributes(method.CustomAttributes);
+ changed |= this.RewriteTypeReference(method.ReturnType, newType => method.ReturnType = newType);
+ changed |= this.RewriteGenericParameters(method.GenericParameters);
+ changed |= this.RewriteCustomAttributes(method.CustomAttributes);
foreach (ParameterDefinition parameter in method.Parameters)
- anyRewritten |= this.RewriteTypeReference(parameter.ParameterType, newType => parameter.ParameterType = newType);
+ changed |= this.RewriteTypeReference(parameter.ParameterType, newType => parameter.ParameterType = newType);
foreach (var methodOverride in method.Overrides)
- anyRewritten |= this.RewriteMethodReference(methodOverride);
+ changed |= this.RewriteMethodReference(methodOverride);
if (method.HasBody)
{
foreach (VariableDefinition variable in method.Body.Variables)
- anyRewritten |= this.RewriteTypeReference(variable.VariableType, newType => variable.VariableType = newType);
+ changed |= this.RewriteTypeReference(variable.VariableType, newType => variable.VariableType = newType);
// check CIL instructions
ILProcessor cil = method.Body.GetILProcessor();
@@ -104,9 +107,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
if (instruction.OpCode.Code == Code.Nop)
continue;
- anyRewritten |= this.RewriteInstruction(instruction, cil, newInstruction =>
+ changed |= this.RewriteInstruction(instruction, cil, newInstruction =>
{
- anyRewritten = true;
+ changed = true;
cil.Replace(instruction, newInstruction);
instruction = newInstruction;
});
@@ -118,11 +121,14 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
{
exception ??= ex;
}
+
+ if (changed)
+ Interlocked.Increment(ref typesChanged);
}
);
return exception == null
- ? anyRewritten
+ ? typesChanged > 0
: throw new Exception($"Rewriting {this.Module.Name} failed.", exception);
}