- Added use internals attrib option to RunConfig
- Changed compilation and resolution to ignore disposed ACLs.
This commit is contained in:
MapleWheels
2023-10-25 05:29:01 -04:00
committed by GitHub
parent 9e48dda739
commit aaa4a91e01
3 changed files with 44 additions and 8 deletions
@@ -574,11 +574,13 @@ public sealed class CsPackageManager : IDisposable
// try compile // try compile
successState = _assemblyManager.LoadAssemblyFromMemory( successState = _assemblyManager.LoadAssemblyFromMemory(
pair.Key.Name.Replace(" ",""), pair.Value.config.UseInternalAssemblyName ? "CompiledAssembly" : pair.Key.Name.Replace(" ",""),
syntaxTrees, syntaxTrees,
null, null,
CompilationOptions, CompilationOptions,
pair.Key.Name, ref id, pair.Value.config.UseNonPublicizedAssemblies ? null : publicizedAssemblies); pair.Key.Name,
ref id,
pair.Value.config.UseNonPublicizedAssemblies ? null : publicizedAssemblies);
if (successState is not AssemblyLoadingSuccessState.Success) if (successState is not AssemblyLoadingSuccessState.Success)
{ {
@@ -5,11 +5,14 @@ using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Loader; using System.Runtime.Loader;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
// ReSharper disable ConditionIsAlwaysTrueOrFalse // ReSharper disable ConditionIsAlwaysTrueOrFalse
[assembly: InternalsVisibleTo("CompiledAssembly")]
namespace Barotrauma; namespace Barotrauma;
/// <summary> /// <summary>
@@ -30,10 +33,12 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
protected bool IsResolving; //this is to avoid circular dependency lookup. protected bool IsResolving; //this is to avoid circular dependency lookup.
private AssemblyManager _assemblyManager; private AssemblyManager _assemblyManager;
public bool IsTemplateMode { get; set; } public bool IsTemplateMode { get; set; }
public bool IsDisposed { get; private set; }
public MemoryFileAssemblyContextLoader(AssemblyManager assemblyManager) : base(isCollectible: true) public MemoryFileAssemblyContextLoader(AssemblyManager assemblyManager) : base(isCollectible: true)
{ {
this._assemblyManager = assemblyManager; this._assemblyManager = assemblyManager;
this.IsDisposed = false;
base.Unloading += OnUnload; base.Unloading += OnUnload;
} }
@@ -157,11 +162,11 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
if (externMetadataReferences is not null) if (externMetadataReferences is not null)
metadataReferences.AddRange(externMetadataReferences); metadataReferences.AddRange(externMetadataReferences);
// build metadata refs from global where not an in-memory compiled assembly and not the same assembly as supplied. // build metadata refs from default where not an in-memory compiled assembly and not the same assembly as supplied.
metadataReferences.AddRange(AppDomain.CurrentDomain.GetAssemblies() metadataReferences.AddRange(AssemblyLoadContext.Default.Assemblies
.Where(a => .Where(a =>
{ {
if (a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit")) if (a.IsDynamic || string.IsNullOrWhiteSpace(a.Location) || a.Location.Contains("xunit"))
return false; return false;
if (a.FullName is null) if (a.FullName is null)
return true; return true;
@@ -172,7 +177,28 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
.Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit"))) .Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit")))
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference) .Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
).ToList()); ).ToList());
// build metadata refs from ACL assemblies from files/disk.
foreach (AssemblyManager.LoadedACL loadedAcl in _assemblyManager.GetAllLoadedACLs())
{
if(loadedAcl.Acl.IsTemplateMode || loadedAcl.Acl.IsDisposed)
continue;
metadataReferences.AddRange(loadedAcl.Acl.Assemblies
.Where(a =>
{
if (a.IsDynamic || string.IsNullOrWhiteSpace(a.Location) || a.Location.Contains("xunit"))
return false;
if (a.FullName is null)
return true;
return !externAssemblyNames.Contains(a.FullName); // exclude duplicates
})
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
.Union(externAssemblyRefs // add custom supplied assemblies
.Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit")))
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
).ToList());
}
// build metadata refs from in-memory images // build metadata refs from in-memory images
foreach (var loadedAcl in _assemblyManager.GetAllLoadedACLs()) foreach (var loadedAcl in _assemblyManager.GetAllLoadedACLs())
{ {
@@ -252,7 +278,8 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
//try resolve against other loaded alcs //try resolve against other loaded alcs
foreach (var loadedAcL in _assemblyManager.GetAllLoadedACLs()) foreach (var loadedAcL in _assemblyManager.GetAllLoadedACLs())
{ {
if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode) continue; if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode || loadedAcL.Acl.IsDisposed)
continue;
try try
{ {
@@ -285,5 +312,6 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
CompiledAssemblyImage = null; CompiledAssemblyImage = null;
_dependencyResolvers.Clear(); _dependencyResolvers.Clear();
base.Unloading -= OnUnload; base.Unloading -= OnUnload;
this.IsDisposed = true;
} }
} }
@@ -33,9 +33,15 @@ public sealed class RunConfig
/// Compiles the mod using non-publicized assemblies. /// Compiles the mod using non-publicized assemblies.
/// </summary> /// </summary>
[XmlElement(ElementName = "UseNonPublicizedAssemblies")] [XmlElement(ElementName = "UseNonPublicizedAssemblies")]
[DefaultValue(false)]
public bool UseNonPublicizedAssemblies { get; set; } public bool UseNonPublicizedAssemblies { get; set; }
/// <summary>
/// If the mod includes source files, the compiled assembly will be named "CompiledAssembly" and have the [InternalVisibleTo()] attribute applied to it.
/// </summary>
[XmlElement(ElementName = "UseInternalAssemblyName")]
[DefaultValue(false)]
public bool UseInternalAssemblyName { get; set; }
[XmlElement(ElementName = "AutoGenerated")] [XmlElement(ElementName = "AutoGenerated")]
public bool AutoGenerated { get; set; } public bool AutoGenerated { get; set; }