feat(cordis): 接入上下文组合与模组事务热替换
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7881ad37b016fc84ea31b463403d901a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
#nullable enable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Mono.Cecil;
|
||||
using Unity.CompilationPipeline.Common.ILPostProcessing;
|
||||
|
||||
namespace ShrinkShared.CodeGen
|
||||
{
|
||||
internal sealed class PostProcessorAssemblyResolver : IAssemblyResolver
|
||||
{
|
||||
private readonly string[] _references;
|
||||
private readonly Dictionary<string, AssemblyDefinition> _cache = new();
|
||||
private AssemblyDefinition? _self;
|
||||
|
||||
public PostProcessorAssemblyResolver(ICompiledAssembly compiledAssembly)
|
||||
{
|
||||
_references = compiledAssembly.References;
|
||||
}
|
||||
|
||||
public void AddAssemblyDefinitionBeingOperatedOn(AssemblyDefinition assemblyDefinition)
|
||||
{
|
||||
_self = assemblyDefinition;
|
||||
}
|
||||
|
||||
public AssemblyDefinition? Resolve(AssemblyNameReference name)
|
||||
=> Resolve(name, new ReaderParameters(ReadingMode.Deferred));
|
||||
|
||||
public AssemblyDefinition? Resolve(AssemblyNameReference name, ReaderParameters parameters)
|
||||
{
|
||||
lock (_cache)
|
||||
{
|
||||
if (name.Name == _self?.Name.Name)
|
||||
return _self;
|
||||
|
||||
var path = FindPath(name);
|
||||
if (path == null)
|
||||
return null;
|
||||
|
||||
var key = $"{path}{File.GetLastWriteTime(path)}";
|
||||
if (_cache.TryGetValue(key, out var cached))
|
||||
return cached;
|
||||
|
||||
parameters.AssemblyResolver = this;
|
||||
var assembly = AssemblyDefinition.ReadAssembly(ReadFileWithRetry(path), parameters);
|
||||
_cache[key] = assembly;
|
||||
return assembly;
|
||||
}
|
||||
}
|
||||
|
||||
private string? FindPath(AssemblyNameReference name)
|
||||
{
|
||||
foreach (var reference in _references)
|
||||
{
|
||||
if (Path.GetFileNameWithoutExtension(reference) == name.Name)
|
||||
return reference;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MemoryStream ReadFileWithRetry(string path, int retries = 5)
|
||||
{
|
||||
for (var i = 0; i < retries; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new MemoryStream(File.ReadAllBytes(path));
|
||||
}
|
||||
catch (IOException) when (i < retries - 1)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IOException($"[ShrinkShared.CodeGen] 无法读取文件: {path}");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b750fb992bcdddc479a883b1b6bf5ef2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#nullable enable
|
||||
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ShrinkShared.CodeGen
|
||||
{
|
||||
internal sealed class PostProcessorReflectionImporter : DefaultReflectionImporter
|
||||
{
|
||||
private const string CoreLibName = "System.Private.CoreLib";
|
||||
private readonly AssemblyNameReference? _corlib;
|
||||
|
||||
public PostProcessorReflectionImporter(ModuleDefinition module)
|
||||
: base(module)
|
||||
{
|
||||
_corlib = module.AssemblyReferences.FirstOrDefault(reference => reference.Name is "mscorlib" or "netstandard");
|
||||
}
|
||||
|
||||
public override AssemblyNameReference ImportReference(AssemblyName reference)
|
||||
{
|
||||
if (_corlib != null && reference.Name == CoreLibName)
|
||||
return _corlib;
|
||||
|
||||
return base.ImportReference(reference);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class PostProcessorReflectionImporterProvider : IReflectionImporterProvider
|
||||
{
|
||||
public IReflectionImporter GetReflectionImporter(ModuleDefinition module)
|
||||
=> new PostProcessorReflectionImporter(module);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31170a0a3448b8f428b07fa251fe5d10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,401 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Pdb;
|
||||
using Unity.CompilationPipeline.Common.Diagnostics;
|
||||
using Unity.CompilationPipeline.Common.ILPostProcessing;
|
||||
|
||||
namespace ShrinkShared.CodeGen
|
||||
{
|
||||
public sealed class ShrinkRegistryILPostProcessor : ILPostProcessor
|
||||
{
|
||||
public override ILPostProcessor GetInstance() => this;
|
||||
|
||||
public override bool WillProcess(ICompiledAssembly compiledAssembly)
|
||||
{
|
||||
// 注意:不能因为"引用了 ShrinkEventBus.Runtime"就处理该程序集。
|
||||
// 一旦把 ShrinkApp.Core.Runtime 等核心程序集卷入 Cecil 读写,写回的 dll
|
||||
// 会被 Unity 判定为 "references itself" 而整条依赖链拒绝加载。
|
||||
// 只处理直接承载 Command/Network/App 注册表的程序集。
|
||||
return compiledAssembly.References.Any(path =>
|
||||
Path.GetFileNameWithoutExtension(path) is "ShrinkCommand.Runtime" or "ShrinkNetwork.Runtime"
|
||||
or "ShrinkApp.Core.Runtime");
|
||||
}
|
||||
|
||||
public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
|
||||
{
|
||||
var diagnostics = new List<DiagnosticMessage>();
|
||||
if (!WillProcess(compiledAssembly))
|
||||
return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics);
|
||||
|
||||
var assemblyDefinition = AssemblyDefinitionFor(compiledAssembly);
|
||||
var module = assemblyDefinition.MainModule;
|
||||
|
||||
try
|
||||
{
|
||||
InjectEventBusAutoRegister(module);
|
||||
InjectShrinkCommandRegistry(module);
|
||||
InjectShrinkNetworkRegistry(module);
|
||||
InjectShrinkAppRegistry(module);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
diagnostics.Add(new DiagnosticMessage
|
||||
{
|
||||
DiagnosticType = DiagnosticType.Error,
|
||||
MessageData = $"[ShrinkShared.CodeGen] {ex.Message}"
|
||||
});
|
||||
}
|
||||
|
||||
return GetResult(assemblyDefinition, diagnostics);
|
||||
}
|
||||
|
||||
private void InjectShrinkCommandRegistry(ModuleDefinition module)
|
||||
{
|
||||
var subscriberType = FindType(module, "ShrinkCommand.ShrinkCommandSubscriberAttribute", "ShrinkCommand.Runtime");
|
||||
var commandAttributeType = FindType(module, "ShrinkCommand.ShrinkCommandAttribute", "ShrinkCommand.Runtime");
|
||||
var registryCtor = FindTypeArrayConstructor(module,
|
||||
"ShrinkCommand.ShrinkCommandStaticRegistryAttribute",
|
||||
"ShrinkCommand.Runtime");
|
||||
|
||||
if (subscriberType == null || commandAttributeType == null || registryCtor == null)
|
||||
return;
|
||||
|
||||
var subscriberTypes = module.Types
|
||||
.Where(type => HasAttribute(type, subscriberType))
|
||||
.Where(type => type.Methods.Any(method => method.IsStatic && HasAttribute(method, commandAttributeType)))
|
||||
.Select(type => module.ImportReference(type))
|
||||
.ToArray();
|
||||
|
||||
if (subscriberTypes.Length > 0)
|
||||
AddAssemblyTypeArrayAttribute(module, registryCtor, subscriberTypes);
|
||||
}
|
||||
|
||||
private void InjectEventBusAutoRegister(ModuleDefinition module)
|
||||
{
|
||||
var subscriberType = FindType(module, "ShrinkEventBus.EventBusSubscriberAttribute", "ShrinkEventBus.Runtime");
|
||||
var eventBusType = FindType(module, "ShrinkEventBus.EventBus", "ShrinkEventBus.Runtime");
|
||||
var subscribeAttributeType = FindType(module, "ShrinkEventBus.EventSubscribeAttribute", "ShrinkEventBus.Runtime");
|
||||
var staticRegistryCtor = FindTypeArrayConstructor(module,
|
||||
"ShrinkEventBus.EventBusStaticRegistryAttribute",
|
||||
"ShrinkEventBus.Runtime");
|
||||
if (subscriberType == null || eventBusType == null)
|
||||
return;
|
||||
|
||||
var eventBusTypeDef = eventBusType.Resolve();
|
||||
var autoRegisterMethod = eventBusTypeDef?.Methods.FirstOrDefault(method =>
|
||||
method.Name == "AutoRegister" &&
|
||||
method.IsStatic &&
|
||||
method.Parameters.Count == 1);
|
||||
var unregisterMethod = eventBusTypeDef?.Methods.FirstOrDefault(method =>
|
||||
method.Name == "UnregisterInstance" &&
|
||||
method.IsStatic &&
|
||||
method.Parameters.Count == 1);
|
||||
if (autoRegisterMethod == null || unregisterMethod == null)
|
||||
return;
|
||||
|
||||
var autoRegisterMethodRef = module.ImportReference(autoRegisterMethod);
|
||||
var unregisterMethodRef = module.ImportReference(unregisterMethod);
|
||||
|
||||
foreach (var type in module.Types)
|
||||
{
|
||||
if (!HasAttribute(type, subscriberType) || !InheritsFromMonoBehaviour(type))
|
||||
continue;
|
||||
|
||||
if (subscribeAttributeType != null && !HasInstanceSubscribeMethod(type, subscribeAttributeType))
|
||||
continue;
|
||||
|
||||
InjectAutoRegister(type, module, autoRegisterMethodRef);
|
||||
InjectAutoUnregister(type, module, unregisterMethodRef);
|
||||
}
|
||||
|
||||
if (subscribeAttributeType != null && staticRegistryCtor != null)
|
||||
{
|
||||
var staticSubscriberTypes = module.Types
|
||||
.Where(type => HasAttribute(type, subscriberType))
|
||||
.Where(type => type.Methods.Any(method => method.IsStatic && HasAttribute(method, subscribeAttributeType)))
|
||||
.Select(type => module.ImportReference(type))
|
||||
.ToArray();
|
||||
if (staticSubscriberTypes.Length > 0)
|
||||
AddAssemblyTypeArrayAttribute(module, staticRegistryCtor, staticSubscriberTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private void InjectShrinkNetworkRegistry(ModuleDefinition module)
|
||||
{
|
||||
var messageAttributeType = FindType(module, "ShrinkNetwork.ShrinkNetworkMessageAttribute", "ShrinkNetwork.Runtime");
|
||||
var subscriberAttributeType = FindType(module, "ShrinkNetwork.ShrinkNetworkSubscriberAttribute", "ShrinkNetwork.Runtime");
|
||||
var subscribeAttributeType = FindType(module, "ShrinkNetwork.ShrinkNetworkSubscribeAttribute", "ShrinkNetwork.Runtime");
|
||||
var messageCtor = FindTypeArrayConstructor(module, "ShrinkNetwork.ShrinkNetworkMessageRegistryAttribute", "ShrinkNetwork.Runtime");
|
||||
var subscriberCtor = FindTypeArrayConstructor(module, "ShrinkNetwork.ShrinkNetworkStaticSubscriberRegistryAttribute", "ShrinkNetwork.Runtime");
|
||||
|
||||
if (messageAttributeType != null && messageCtor != null)
|
||||
{
|
||||
var messageTypes = module.Types
|
||||
.Where(type => HasAttribute(type, messageAttributeType))
|
||||
.Select(type => module.ImportReference(type))
|
||||
.ToArray();
|
||||
if (messageTypes.Length > 0)
|
||||
AddAssemblyTypeArrayAttribute(module, messageCtor, messageTypes);
|
||||
}
|
||||
|
||||
if (subscriberAttributeType != null && subscribeAttributeType != null && subscriberCtor != null)
|
||||
{
|
||||
var subscriberTypes = module.Types
|
||||
.Where(type => HasAttribute(type, subscriberAttributeType))
|
||||
.Where(type => type.Methods.Any(method => method.IsStatic && HasAttribute(method, subscribeAttributeType)))
|
||||
.Select(type => module.ImportReference(type))
|
||||
.ToArray();
|
||||
if (subscriberTypes.Length > 0)
|
||||
AddAssemblyTypeArrayAttribute(module, subscriberCtor, subscriberTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private void InjectShrinkAppRegistry(ModuleDefinition module)
|
||||
{
|
||||
var installerAttributeType = FindType(module, "ShrinkApp.ShrinkAppModuleInstallerAttribute", "ShrinkApp.Core.Runtime");
|
||||
var installerInterfaceType = FindType(module, "ShrinkApp.IShrinkAppModuleInstaller", "ShrinkApp.Core.Runtime");
|
||||
var registryCtor = FindTypeArrayConstructor(module, "ShrinkApp.ShrinkAppInstallerRegistryAttribute", "ShrinkApp.Core.Runtime");
|
||||
|
||||
if (installerAttributeType == null || installerInterfaceType == null || registryCtor == null)
|
||||
return;
|
||||
|
||||
var installerTypes = module.Types
|
||||
.Where(type => !type.IsAbstract)
|
||||
.Where(type => HasAttribute(type, installerAttributeType))
|
||||
.Where(type => type.Interfaces.Any(item => item.InterfaceType.FullName == installerInterfaceType.FullName))
|
||||
.Select(type => module.ImportReference(type))
|
||||
.ToArray();
|
||||
|
||||
if (installerTypes.Length > 0)
|
||||
AddAssemblyTypeArrayAttribute(module, registryCtor, installerTypes);
|
||||
}
|
||||
|
||||
private static bool HasAttribute(ICustomAttributeProvider provider, TypeReference expectedAttributeType)
|
||||
{
|
||||
return provider.CustomAttributes.Any(attribute => attribute.AttributeType.FullName == expectedAttributeType.FullName);
|
||||
}
|
||||
|
||||
private static bool HasInstanceSubscribeMethod(TypeDefinition type, TypeReference subscribeAttributeType)
|
||||
{
|
||||
var current = type;
|
||||
while (current != null && current.Name != "MonoBehaviour")
|
||||
{
|
||||
if (current.Methods.Any(method => !method.IsStatic && HasAttribute(method, subscribeAttributeType)))
|
||||
return true;
|
||||
|
||||
var baseTypeRef = current.BaseType;
|
||||
if (baseTypeRef == null)
|
||||
return false;
|
||||
|
||||
TypeDefinition? resolvedBase;
|
||||
try
|
||||
{
|
||||
resolvedBase = baseTypeRef.Resolve();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (resolvedBase == null)
|
||||
return true;
|
||||
|
||||
current = resolvedBase;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool InheritsFromMonoBehaviour(TypeDefinition type)
|
||||
{
|
||||
var current = type.BaseType;
|
||||
while (current != null)
|
||||
{
|
||||
if (current.Name == "MonoBehaviour")
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
current = current.Resolve()?.BaseType;
|
||||
}
|
||||
catch
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void InjectAutoRegister(TypeDefinition type, ModuleDefinition module, MethodReference autoRegisterMethodRef)
|
||||
{
|
||||
var awake = type.Methods.FirstOrDefault(method => method.Name == "Awake" && !method.IsStatic);
|
||||
if (awake == null)
|
||||
{
|
||||
var baseAwakeRef = FindBaseMethodReference(type, "Awake", module);
|
||||
if (baseAwakeRef != null)
|
||||
{
|
||||
awake = new MethodDefinition("Awake",
|
||||
MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual,
|
||||
module.TypeSystem.Void);
|
||||
var il = awake.Body.GetILProcessor();
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Call, baseAwakeRef);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Call, autoRegisterMethodRef);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Ret);
|
||||
type.Methods.Add(awake);
|
||||
return;
|
||||
}
|
||||
|
||||
awake = new MethodDefinition("Awake",
|
||||
MethodAttributes.Private | MethodAttributes.HideBySig,
|
||||
module.TypeSystem.Void);
|
||||
var retIl = awake.Body.GetILProcessor();
|
||||
retIl.Emit(Mono.Cecil.Cil.OpCodes.Ret);
|
||||
type.Methods.Add(awake);
|
||||
}
|
||||
|
||||
var processor = awake.Body.GetILProcessor();
|
||||
var instructions = new List<Mono.Cecil.Cil.Instruction>
|
||||
{
|
||||
processor.Create(Mono.Cecil.Cil.OpCodes.Ldarg_0),
|
||||
processor.Create(Mono.Cecil.Cil.OpCodes.Call, autoRegisterMethodRef),
|
||||
processor.Create(Mono.Cecil.Cil.OpCodes.Nop)
|
||||
};
|
||||
instructions.Reverse();
|
||||
instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction));
|
||||
}
|
||||
|
||||
private static void InjectAutoUnregister(TypeDefinition type, ModuleDefinition module, MethodReference unregisterMethodRef)
|
||||
{
|
||||
var onDestroy = type.Methods.FirstOrDefault(method => method.Name == "OnDestroy" && !method.IsStatic);
|
||||
if (onDestroy == null)
|
||||
{
|
||||
var baseOnDestroyRef = FindBaseMethodReference(type, "OnDestroy", module);
|
||||
if (baseOnDestroyRef != null)
|
||||
{
|
||||
onDestroy = new MethodDefinition("OnDestroy",
|
||||
MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual,
|
||||
module.TypeSystem.Void);
|
||||
var il = onDestroy.Body.GetILProcessor();
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Call, unregisterMethodRef);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Call, baseOnDestroyRef);
|
||||
il.Emit(Mono.Cecil.Cil.OpCodes.Ret);
|
||||
type.Methods.Add(onDestroy);
|
||||
return;
|
||||
}
|
||||
|
||||
onDestroy = new MethodDefinition("OnDestroy",
|
||||
MethodAttributes.Private | MethodAttributes.HideBySig,
|
||||
module.TypeSystem.Void);
|
||||
var retIl = onDestroy.Body.GetILProcessor();
|
||||
retIl.Emit(Mono.Cecil.Cil.OpCodes.Ret);
|
||||
type.Methods.Add(onDestroy);
|
||||
}
|
||||
|
||||
var processor = onDestroy.Body.GetILProcessor();
|
||||
var instructions = new List<Mono.Cecil.Cil.Instruction>
|
||||
{
|
||||
processor.Create(Mono.Cecil.Cil.OpCodes.Ldarg_0),
|
||||
processor.Create(Mono.Cecil.Cil.OpCodes.Call, unregisterMethodRef),
|
||||
processor.Create(Mono.Cecil.Cil.OpCodes.Nop)
|
||||
};
|
||||
instructions.Reverse();
|
||||
instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction));
|
||||
}
|
||||
|
||||
private static MethodReference? FindBaseMethodReference(TypeDefinition type, string methodName, ModuleDefinition module)
|
||||
{
|
||||
try
|
||||
{
|
||||
var baseTypeRef = type.BaseType;
|
||||
while (baseTypeRef != null)
|
||||
{
|
||||
var baseTypeDef = baseTypeRef.Resolve();
|
||||
if (baseTypeDef == null)
|
||||
break;
|
||||
|
||||
var method = baseTypeDef.Methods.FirstOrDefault(candidate =>
|
||||
candidate.Name == methodName && !candidate.IsStatic && candidate.IsVirtual);
|
||||
if (method != null)
|
||||
return module.ImportReference(method);
|
||||
|
||||
baseTypeRef = baseTypeDef.BaseType;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void AddAssemblyTypeArrayAttribute(ModuleDefinition module, MethodReference ctor, TypeReference[] types)
|
||||
{
|
||||
var attribute = new CustomAttribute(ctor);
|
||||
var typeTypeRef = module.ImportReference(typeof(Type));
|
||||
attribute.ConstructorArguments.Add(new CustomAttributeArgument(
|
||||
module.ImportReference(typeof(Type[])),
|
||||
types.Select(type => new CustomAttributeArgument(typeTypeRef, type)).ToArray()));
|
||||
module.Assembly.CustomAttributes.Add(attribute);
|
||||
}
|
||||
|
||||
private static TypeReference? FindType(ModuleDefinition module, string fullName, string assemblyName)
|
||||
{
|
||||
var resolved = Type.GetType($"{fullName}, {assemblyName}", false);
|
||||
return resolved == null ? null : module.ImportReference(resolved);
|
||||
}
|
||||
|
||||
private static MethodReference? FindTypeArrayConstructor(ModuleDefinition module, string fullName, string assemblyName)
|
||||
{
|
||||
var typeRef = FindType(module, fullName, assemblyName);
|
||||
var typeDef = typeRef?.Resolve();
|
||||
var ctor = typeDef?.Methods.FirstOrDefault(method =>
|
||||
method.IsConstructor &&
|
||||
method.Parameters.Count == 1 &&
|
||||
method.Parameters[0].ParameterType.IsArray &&
|
||||
method.Parameters[0].ParameterType.GetElementType().FullName == module.ImportReference(typeof(Type)).FullName);
|
||||
return ctor == null ? null : module.ImportReference(ctor);
|
||||
}
|
||||
|
||||
private static AssemblyDefinition AssemblyDefinitionFor(ICompiledAssembly compiledAssembly)
|
||||
{
|
||||
var assemblyResolver = new PostProcessorAssemblyResolver(compiledAssembly);
|
||||
var readerParameters = new ReaderParameters
|
||||
{
|
||||
SymbolStream = new MemoryStream(compiledAssembly.InMemoryAssembly.PdbData.ToArray()),
|
||||
SymbolReaderProvider = new PdbReaderProvider(),
|
||||
AssemblyResolver = assemblyResolver,
|
||||
ReflectionImporterProvider = new PostProcessorReflectionImporterProvider(),
|
||||
ReadingMode = ReadingMode.Immediate
|
||||
};
|
||||
|
||||
var assemblyDefinition = AssemblyDefinition.ReadAssembly(
|
||||
new MemoryStream(compiledAssembly.InMemoryAssembly.PeData.ToArray()),
|
||||
readerParameters);
|
||||
assemblyResolver.AddAssemblyDefinitionBeingOperatedOn(assemblyDefinition);
|
||||
return assemblyDefinition;
|
||||
}
|
||||
|
||||
private static ILPostProcessResult GetResult(AssemblyDefinition assemblyDefinition, List<DiagnosticMessage> diagnostics)
|
||||
{
|
||||
var pe = new MemoryStream();
|
||||
var pdb = new MemoryStream();
|
||||
assemblyDefinition.Write(pe, new WriterParameters
|
||||
{
|
||||
SymbolWriterProvider = new PdbWriterProvider(),
|
||||
SymbolStream = pdb,
|
||||
WriteSymbols = true
|
||||
});
|
||||
return new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f07f372d8ceeed47aa4e5702fd1adef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "Unity.ShrinkShared.CodeGen",
|
||||
"rootNamespace": "ShrinkShared.CodeGen",
|
||||
"references": [
|
||||
"ShrinkEventBus.Runtime",
|
||||
"ShrinkCommand.Runtime",
|
||||
"ShrinkNetwork.Runtime",
|
||||
"ShrinkApp.Core.Runtime"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"Unity.Burst.Cecil.dll",
|
||||
"Unity.Burst.Cecil.Mdb.dll",
|
||||
"Unity.Burst.Cecil.Pdb.dll",
|
||||
"Unity.Burst.Cecil.Rocks.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89b1954231cba2541ab97b45f6a407fe
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user