From ebc603844a3931bedbd512761ba8f152a4f5a09c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 19:49:34 -0400 Subject: update to Mono.Cecil 0.10 --- .../ModLoading/AssemblyDefinitionResolver.cs | 9 ------ src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 37 +++++++++++++++------- .../Framework/ModLoading/PlatformAssemblyMap.cs | 12 +++++-- .../ModLoading/Rewriters/FieldReplaceRewriter.cs | 2 +- .../Rewriters/FieldToPropertyRewriter.cs | 2 +- .../ModLoading/Rewriters/MethodParentRewriter.cs | 2 +- .../ModLoading/Rewriters/TypeReferenceRewriter.cs | 2 +- src/SMAPI/Program.cs | 4 +-- src/SMAPI/StardewModdingAPI.csproj | 12 +++---- src/SMAPI/packages.config | 2 +- 10 files changed, 48 insertions(+), 36 deletions(-) (limited to 'src/SMAPI') diff --git a/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs b/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs index d85a9a28..33cd6ebd 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs @@ -36,15 +36,6 @@ namespace StardewModdingAPI.Framework.ModLoading /// The assembly reader parameters. public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) => this.ResolveName(name.Name) ?? base.Resolve(name, parameters); - /// Resolve an assembly reference. - /// The assembly full name (including version, etc). - public override AssemblyDefinition Resolve(string fullName) => this.ResolveName(fullName) ?? base.Resolve(fullName); - - /// Resolve an assembly reference. - /// The assembly full name (including version, etc). - /// The assembly reader parameters. - public override AssemblyDefinition Resolve(string fullName, ReaderParameters parameters) => this.ResolveName(fullName) ?? base.Resolve(fullName, parameters); - /********* ** Private methods diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 2fb2aba7..d41774a9 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -12,7 +12,7 @@ using StardewModdingAPI.Metadata; namespace StardewModdingAPI.Framework.ModLoading { /// Preprocesses and loads mod assemblies. - internal class AssemblyLoader + internal class AssemblyLoader : IDisposable { /********* ** Properties @@ -20,9 +20,6 @@ namespace StardewModdingAPI.Framework.ModLoading /// Encapsulates monitoring and logging. private readonly IMonitor Monitor; - /// Whether to enable developer mode logging. - private readonly bool IsDeveloperMode; - /// Metadata for mapping assemblies to the current platform. private readonly PlatformAssemblyMap AssemblyMap; @@ -32,6 +29,9 @@ namespace StardewModdingAPI.Framework.ModLoading /// A minimal assembly definition resolver which resolves references to known loaded assemblies. private readonly AssemblyDefinitionResolver AssemblyDefinitionResolver; + /// The objects to dispose as part of this instance. + private readonly HashSet Disposables = new HashSet(); + /********* ** Public methods @@ -39,13 +39,11 @@ namespace StardewModdingAPI.Framework.ModLoading /// Construct an instance. /// The current game platform. /// Encapsulates monitoring and logging. - /// Whether to enable developer mode logging. - public AssemblyLoader(Platform targetPlatform, IMonitor monitor, bool isDeveloperMode) + public AssemblyLoader(Platform targetPlatform, IMonitor monitor) { this.Monitor = monitor; - this.IsDeveloperMode = isDeveloperMode; - this.AssemblyMap = Constants.GetAssemblyMap(targetPlatform); - this.AssemblyDefinitionResolver = new AssemblyDefinitionResolver(); + this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform)); + this.AssemblyDefinitionResolver = this.TrackForDisposal(new AssemblyDefinitionResolver()); // generate type => assembly lookup for types which should be rewritten this.TypeAssemblies = new Dictionary(); @@ -144,10 +142,26 @@ namespace StardewModdingAPI.Framework.ModLoading .FirstOrDefault(p => p.GetName().Name == shortName); } + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public void Dispose() + { + foreach (IDisposable instance in this.Disposables) + instance.Dispose(); + } + /********* ** Private methods *********/ + /// Track an object for disposal as part of the assembly loader. + /// The instance type. + /// The disposable instance. + private T TrackForDisposal(T instance) where T : IDisposable + { + this.Disposables.Add(instance); + return instance; + } + /**** ** Assembly parsing ****/ @@ -166,9 +180,8 @@ namespace StardewModdingAPI.Framework.ModLoading // read assembly byte[] assemblyBytes = File.ReadAllBytes(file.FullName); - AssemblyDefinition assembly; - using (Stream readStream = new MemoryStream(assemblyBytes)) - assembly = AssemblyDefinition.ReadAssembly(readStream, new ReaderParameters(ReadingMode.Deferred) { AssemblyResolver = assemblyResolver }); + Stream readStream = this.TrackForDisposal(new MemoryStream(assemblyBytes)); + AssemblyDefinition assembly = this.TrackForDisposal(AssemblyDefinition.ReadAssembly(readStream, new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = assemblyResolver, InMemory = true })); // skip if already visited if (visitedAssemblyNames.Contains(assembly.Name.Name)) diff --git a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs index f0a28b4a..01460dce 100644 --- a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs +++ b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -7,7 +8,7 @@ using StardewModdingAPI.Internal; namespace StardewModdingAPI.Framework.ModLoading { /// Metadata for mapping assemblies to the current . - internal class PlatformAssemblyMap + internal class PlatformAssemblyMap : IDisposable { /********* ** Accessors @@ -50,7 +51,14 @@ namespace StardewModdingAPI.Framework.ModLoading // cache assembly metadata this.Targets = targetAssemblies; this.TargetReferences = this.Targets.ToDictionary(assembly => assembly, assembly => AssemblyNameReference.Parse(assembly.FullName)); - this.TargetModules = this.Targets.ToDictionary(assembly => assembly, assembly => ModuleDefinition.ReadModule(assembly.Modules.Single().FullyQualifiedName)); + this.TargetModules = this.Targets.ToDictionary(assembly => assembly, assembly => ModuleDefinition.ReadModule(assembly.Modules.Single().FullyQualifiedName, new ReaderParameters { InMemory = true })); + } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public void Dispose() + { + foreach (ModuleDefinition module in this.TargetModules.Values) + module.Dispose(); } } } diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs index 63358b39..806a074f 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs @@ -42,7 +42,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters if (!this.IsMatch(instruction)) return InstructionHandleResult.None; - FieldReference newRef = module.Import(this.ToField); + FieldReference newRef = module.ImportReference(this.ToField); cil.Replace(instruction, cil.Create(instruction.OpCode, newRef)); return InstructionHandleResult.Rewritten; } diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs index b1fa377a..e6ede9e3 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs @@ -50,7 +50,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters return InstructionHandleResult.None; string methodPrefix = instruction.OpCode == OpCodes.Ldsfld || instruction.OpCode == OpCodes.Ldfld ? "get" : "set"; - MethodReference propertyRef = module.Import(this.Type.GetMethod($"{methodPrefix}_{this.PropertyName}")); + MethodReference propertyRef = module.ImportReference(this.Type.GetMethod($"{methodPrefix}_{this.PropertyName}")); cil.Replace(instruction, cil.Create(OpCodes.Call, propertyRef)); return InstructionHandleResult.Rewritten; diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs index 974fcf4c..99bd9125 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs @@ -64,7 +64,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters return InstructionHandleResult.None; MethodReference methodRef = (MethodReference)instruction.Operand; - methodRef.DeclaringType = module.Import(this.ToType); + methodRef.DeclaringType = module.ImportReference(this.ToType); return InstructionHandleResult.Rewritten; } diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs index 74f2fcdd..5c7db902 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs @@ -135,7 +135,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters { // root type if (type.FullName == this.FromTypeName) - return module.Import(this.ToType); + return module.ImportReference(this.ToType); // generic arguments if (type is GenericInstanceType genericType) diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 53f3749a..7b5176a0 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -686,7 +686,7 @@ namespace StardewModdingAPI // show update errors if (errors.Length != 0) - this.Monitor.Log("Encountered errors fetching updates for some mods:\n" + errors.ToString(), LogLevel.Trace); + this.Monitor.Log("Encountered errors fetching updates for some mods:\n" + errors, LogLevel.Trace); // show update alerts if (updates.Any()) @@ -796,7 +796,7 @@ namespace StardewModdingAPI ); // get assembly loaders - AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor, this.Settings.DeveloperMode); + AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor); AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => modAssemblyLoader.ResolveAssembly(e.Name); InterfaceProxyFactory proxyFactory = new InterfaceProxyFactory(); diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index bd9e2422..2e3ba1cd 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -58,16 +58,16 @@ False ..\lib\0Harmony.dll - - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll + + ..\packages\Mono.Cecil.0.10.0\lib\net40\Mono.Cecil.dll True - - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll + + ..\packages\Mono.Cecil.0.10.0\lib\net40\Mono.Cecil.Mdb.dll True - - ..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll + + ..\packages\Mono.Cecil.0.10.0\lib\net40\Mono.Cecil.Pdb.dll True diff --git a/src/SMAPI/packages.config b/src/SMAPI/packages.config index 3347b037..84c6bed0 100644 --- a/src/SMAPI/packages.config +++ b/src/SMAPI/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file -- cgit