#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(); #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()), diagnostics); } catch (Exception exception) { diagnostics.Add(new DiagnosticMessage { DiagnosticType = DiagnosticType.Error, MessageData = $"[ShrinkEventBus.CodeGen] {exception.Message}" }); } #endif return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics); } } }