diff options
Diffstat (limited to 'src/SMAPI/Framework/ModLoading')
-rw-r--r-- | src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs | 34 |
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); } |