summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-05-01 18:16:09 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-05-01 18:16:09 -0400
commitc8ad50dad1d706a1901798f9396f6becfea36c0e (patch)
tree28bd818a5db39ec5ece1bd141a28de955950463b /src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
parent451b70953ff4c0b1b27ae0de203ad99379b45b2a (diff)
parentf78093bdb58d477b400cde3f19b70ffd6ddf833d (diff)
downloadSMAPI-c8ad50dad1d706a1901798f9396f6becfea36c0e.tar.gz
SMAPI-c8ad50dad1d706a1901798f9396f6becfea36c0e.tar.bz2
SMAPI-c8ad50dad1d706a1901798f9396f6becfea36c0e.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Framework/ModLoading/AssemblyLoader.cs')
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs53
1 files changed, 30 insertions, 23 deletions
diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
index cb5fa2ae..72b547b1 100644
--- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
+++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
@@ -36,13 +36,13 @@ namespace StardewModdingAPI.Framework.ModLoading
private readonly AssemblyDefinitionResolver AssemblyDefinitionResolver;
/// <summary>Provides assembly symbol readers for Mono.Cecil.</summary>
- private readonly SymbolReaderProvider SymbolReaderProvider = new SymbolReaderProvider();
+ private readonly SymbolReaderProvider SymbolReaderProvider = new();
/// <summary>Provides assembly symbol writers for Mono.Cecil.</summary>
- private readonly SymbolWriterProvider SymbolWriterProvider = new SymbolWriterProvider();
+ private readonly SymbolWriterProvider SymbolWriterProvider = new();
/// <summary>The objects to dispose as part of this instance.</summary>
- private readonly HashSet<IDisposable> Disposables = new HashSet<IDisposable>();
+ private readonly HashSet<IDisposable> Disposables = new();
/// <summary>Whether to rewrite mods for compatibility.</summary>
private readonly bool RewriteMods;
@@ -94,7 +94,12 @@ namespace StardewModdingAPI.Framework.ModLoading
// get referenced local assemblies
AssemblyParseResult[] assemblies;
{
- HashSet<string> visitedAssemblyNames = new HashSet<string>(AppDomain.CurrentDomain.GetAssemblies().Select(p => p.GetName().Name)); // don't try loading assemblies that are already loaded
+ HashSet<string> visitedAssemblyNames = new HashSet<string>( // don't try loading assemblies that are already loaded
+ from assembly in AppDomain.CurrentDomain.GetAssemblies()
+ let name = assembly.GetName().Name
+ where name != null
+ select name
+ );
assemblies = this.GetReferencedLocalAssemblies(new FileInfo(assemblyPath), visitedAssemblyNames, this.AssemblyDefinitionResolver).ToArray();
}
@@ -111,11 +116,11 @@ namespace StardewModdingAPI.Framework.ModLoading
// rewrite & load assemblies in leaf-to-root order
bool oneAssembly = assemblies.Length == 1;
- Assembly lastAssembly = null;
+ Assembly? lastAssembly = null;
HashSet<string> loggedMessages = new HashSet<string>();
foreach (AssemblyParseResult assembly in assemblies)
{
- if (assembly.Status == AssemblyLoadStatus.AlreadyLoaded)
+ if (!assembly.HasDefinition)
continue;
// rewrite assembly
@@ -138,11 +143,11 @@ namespace StardewModdingAPI.Framework.ModLoading
if (changed)
{
if (!oneAssembly)
- this.Monitor.Log($" Loading {assembly.File.Name} (rewritten)...", LogLevel.Trace);
+ this.Monitor.Log($" Loading {assembly.File.Name} (rewritten)...");
// load assembly
- using MemoryStream outAssemblyStream = new MemoryStream();
- using MemoryStream outSymbolStream = new MemoryStream();
+ using MemoryStream outAssemblyStream = new();
+ using MemoryStream outSymbolStream = new();
assembly.Definition.Write(outAssemblyStream, new WriterParameters { WriteSymbols = true, SymbolStream = outSymbolStream, SymbolWriterProvider = this.SymbolWriterProvider });
byte[] bytes = outAssemblyStream.ToArray();
lastAssembly = Assembly.Load(bytes, outSymbolStream.ToArray());
@@ -150,7 +155,7 @@ namespace StardewModdingAPI.Framework.ModLoading
else
{
if (!oneAssembly)
- this.Monitor.Log($" Loading {assembly.File.Name}...", LogLevel.Trace);
+ this.Monitor.Log($" Loading {assembly.File.Name}...");
lastAssembly = Assembly.UnsafeLoadFrom(assembly.File.FullName);
}
@@ -163,7 +168,7 @@ namespace StardewModdingAPI.Framework.ModLoading
throw new IncompatibleInstructionException();
// last assembly loaded is the root
- return lastAssembly;
+ return lastAssembly!;
}
/// <summary>Get whether an assembly is loaded.</summary>
@@ -172,7 +177,8 @@ namespace StardewModdingAPI.Framework.ModLoading
{
try
{
- return this.AssemblyDefinitionResolver.Resolve(reference) != null;
+ _ = this.AssemblyDefinitionResolver.Resolve(reference);
+ return true;
}
catch (AssemblyResolutionException)
{
@@ -188,7 +194,7 @@ namespace StardewModdingAPI.Framework.ModLoading
/// assemblies (especially with Mono). Since this is meant to be called on <see cref="AppDomain.AssemblyResolve"/>,
/// the implicit assumption is that loading the exact assembly failed.
/// </remarks>
- public static Assembly ResolveAssembly(string name)
+ public static Assembly? ResolveAssembly(string name)
{
string shortName = name.Split(new[] { ',' }, 2).First(); // get simple name (without version and culture)
return AppDomain.CurrentDomain
@@ -210,7 +216,8 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Track an object for disposal as part of the assembly loader.</summary>
/// <typeparam name="T">The instance type.</typeparam>
/// <param name="instance">The disposable instance.</param>
- private T TrackForDisposal<T>(T instance) where T : IDisposable
+ private T TrackForDisposal<T>(T instance)
+ where T : IDisposable
{
this.Disposables.Add(instance);
return instance;
@@ -241,7 +248,7 @@ namespace StardewModdingAPI.Framework.ModLoading
try
{
// read assembly with symbols
- FileInfo symbolsFile = new FileInfo(Path.Combine(Path.GetDirectoryName(file.FullName)!, Path.GetFileNameWithoutExtension(file.FullName)) + ".pdb");
+ FileInfo symbolsFile = new(Path.Combine(Path.GetDirectoryName(file.FullName)!, Path.GetFileNameWithoutExtension(file.FullName)) + ".pdb");
if (symbolsFile.Exists)
this.SymbolReaderProvider.TryAddSymbolData(file.Name, () => this.TrackForDisposal(symbolsFile.OpenRead()));
assembly = this.TrackForDisposal(AssemblyDefinition.ReadAssembly(readStream, new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = assemblyResolver, InMemory = true, ReadSymbols = true, SymbolReaderProvider = this.SymbolReaderProvider }));
@@ -266,7 +273,7 @@ namespace StardewModdingAPI.Framework.ModLoading
// yield referenced assemblies
foreach (AssemblyNameReference dependency in assembly.MainModule.AssemblyReferences)
{
- FileInfo dependencyFile = new FileInfo(Path.Combine(file.Directory.FullName, $"{dependency.Name}.dll"));
+ FileInfo dependencyFile = new(Path.Combine(file.Directory.FullName, $"{dependency.Name}.dll"));
foreach (AssemblyParseResult result in this.GetReferencedLocalAssemblies(dependencyFile, visitedAssemblyNames, assemblyResolver))
yield return result;
}
@@ -319,9 +326,9 @@ namespace StardewModdingAPI.Framework.ModLoading
// rewrite types using custom attributes
foreach (TypeDefinition type in module.GetTypes())
{
- foreach (var attr in type.CustomAttributes)
+ foreach (CustomAttribute attr in type.CustomAttributes)
{
- foreach (var conField in attr.ConstructorArguments)
+ foreach (CustomAttributeArgument conField in attr.ConstructorArguments)
{
if (conField.Value is TypeReference typeRef)
this.ChangeTypeScope(typeRef);
@@ -333,7 +340,7 @@ namespace StardewModdingAPI.Framework.ModLoading
// find or rewrite code
IInstructionHandler[] handlers = new InstructionMetadata().GetHandlers(this.ParanoidMode, platformChanged, this.RewriteMods).ToArray();
- RecursiveRewriter rewriter = new RecursiveRewriter(
+ RecursiveRewriter rewriter = new(
module: module,
rewriteModule: curModule =>
{
@@ -380,7 +387,7 @@ namespace StardewModdingAPI.Framework.ModLoading
{
// get message template
// ($phrase is replaced with the noun phrase or messages)
- string template = null;
+ string? template = null;
switch (result)
{
case InstructionHandleResult.Rewritten:
@@ -439,20 +446,20 @@ namespace StardewModdingAPI.Framework.ModLoading
// format messages
string phrase = handler.Phrases.Any()
? string.Join(", ", handler.Phrases)
- : handler.DefaultPhrase ?? handler.GetType().Name;
+ : handler.DefaultPhrase;
this.Monitor.LogOnce(loggedMessages, template.Replace("$phrase", phrase));
}
/// <summary>Get the correct reference to use for compatibility with the current platform.</summary>
/// <param name="type">The type reference to rewrite.</param>
- private void ChangeTypeScope(TypeReference type)
+ private void ChangeTypeScope(TypeReference? type)
{
// check skip conditions
if (type == null || type.FullName.StartsWith("System."))
return;
// get assembly
- if (!this.TypeAssemblies.TryGetValue(type.FullName, out Assembly assembly))
+ if (!this.TypeAssemblies.TryGetValue(type.FullName, out Assembly? assembly))
return;
// replace scope