Files
ShrinkEventBus/CodeGen/Editor/EventBusILPostProcessor.cs
T

80 lines
3.6 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Unity.CompilationPipeline.Common.Diagnostics;
using Unity.CompilationPipeline.Common.ILPostProcessing;
namespace ShrinkEventBus.CodeGen
{
public sealed class EventBusILPostProcessor : ILPostProcessor
{
public override ILPostProcessor GetInstance() => this;
public override bool WillProcess(ICompiledAssembly compiledAssembly)
{
#if SHRINK_EVENTBUS_HAS_SHARED_CODEGEN
// The shared processor owns event weaving when its package is installed.
return false;
#else
return compiledAssembly.Name != "ShrinkEventBus.Runtime" &&
compiledAssembly.References.Any(path =>
Path.GetFileNameWithoutExtension(path) == "ShrinkEventBus.Runtime");
#endif
}
public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
{
var diagnostics = new List<DiagnosticMessage>();
#if !SHRINK_EVENTBUS_HAS_SHARED_CODEGEN
if (!WillProcess(compiledAssembly))
return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics);
try
{
using var resolver = new PostProcessorAssemblyResolver(compiledAssembly);
using var pe = new MemoryStream(compiledAssembly.InMemoryAssembly.PeData);
var pdbData = compiledAssembly.InMemoryAssembly.PdbData;
var hasSymbols = pdbData != null && pdbData.Length > 0;
using var pdb = hasSymbols ? new MemoryStream(pdbData!) : null;
using var assembly = AssemblyDefinition.ReadAssembly(pe, new ReaderParameters
{
AssemblyResolver = resolver,
ReadingMode = ReadingMode.Immediate,
ReflectionImporterProvider = new PostProcessorReflectionImporterProvider(),
ReadSymbols = hasSymbols,
SymbolStream = pdb,
SymbolReaderProvider = hasSymbols ? new PortablePdbReaderProvider() : null
});
resolver.AddAssemblyDefinitionBeingOperatedOn(assembly);
if (assembly.Name.HasPublicKey)
throw new InvalidOperationException("Signed assemblies cannot be woven by the standalone EventBus processor.");
if (!EventBusAssemblyWeaver.Weave(assembly.MainModule))
return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics);
using var outputPe = new MemoryStream();
using var outputPdb = new MemoryStream();
assembly.Write(outputPe, new WriterParameters
{
WriteSymbols = hasSymbols,
SymbolStream = hasSymbols ? outputPdb : null,
SymbolWriterProvider = hasSymbols ? new PortablePdbWriterProvider() : null
});
return new ILPostProcessResult(new InMemoryAssembly(outputPe.ToArray(),
hasSymbols ? outputPdb.ToArray() : Array.Empty<byte>()), diagnostics);
}
catch (Exception exception)
{
diagnostics.Add(new DiagnosticMessage
{
DiagnosticType = DiagnosticType.Error,
MessageData = $"[ShrinkEventBus.CodeGen] {exception.Message}"
});
}
#endif
return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics);
}
}
}