Files
ShrinkShared.CodeGen/Editor/UnityShrinkCodeGenAdapter.cs

77 lines
3.5 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ShrinkSDK.CodeGen;
using Unity.CompilationPipeline.Common.Diagnostics;
using Unity.CompilationPipeline.Common.ILPostProcessing;
namespace ShrinkShared.CodeGen
{
public static class UnityShrinkCodeGenAdapter
{
public static ILPostProcessResult Process(ICompiledAssembly compiledAssembly, string diagnosticPrefix)
{
var diagnostics = new List<DiagnosticMessage>();
var tempRoot = Path.Combine(Path.GetTempPath(), "ShrinkSDK.CodeGen", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempRoot);
try
{
var inputAssembly = Path.Combine(tempRoot, compiledAssembly.Name + ".dll");
var inputPdb = Path.Combine(tempRoot, compiledAssembly.Name + ".pdb");
var outputAssembly = Path.Combine(tempRoot, compiledAssembly.Name + ".woven.dll");
var outputPdb = Path.Combine(tempRoot, compiledAssembly.Name + ".woven.pdb");
File.WriteAllBytes(inputAssembly, compiledAssembly.InMemoryAssembly.PeData);
var hasSymbols = compiledAssembly.InMemoryAssembly.PdbData != null &&
compiledAssembly.InMemoryAssembly.PdbData.Length > 0;
if (hasSymbols)
File.WriteAllBytes(inputPdb, compiledAssembly.InMemoryAssembly.PdbData);
var result = ShrinkAssemblyWeaver.Weave(inputAssembly, hasSymbols ? inputPdb : null,
compiledAssembly.References, outputAssembly, hasSymbols ? outputPdb : null,
ShrinkCodeGenPlatform.Unity);
foreach (var item in result.Diagnostics)
{
diagnostics.Add(new DiagnosticMessage
{
DiagnosticType = item.Severity == ShrinkCodeGenDiagnosticSeverity.Error
? DiagnosticType.Error
: DiagnosticType.Warning,
MessageData = $"[{diagnosticPrefix}] {item.Message}"
});
}
if (!result.Succeeded || !result.Changed)
return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics);
var pe = File.ReadAllBytes(outputAssembly);
var pdb = hasSymbols && File.Exists(outputPdb)
? File.ReadAllBytes(outputPdb)
: compiledAssembly.InMemoryAssembly.PdbData ?? Array.Empty<byte>();
return new ILPostProcessResult(new InMemoryAssembly(pe, pdb), diagnostics);
}
catch (Exception exception)
{
diagnostics.Add(new DiagnosticMessage
{
DiagnosticType = DiagnosticType.Error,
MessageData = $"[{diagnosticPrefix}] {exception.Message}"
});
return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics);
}
finally
{
try { Directory.Delete(tempRoot, true); }
catch { }
}
}
public static bool ReferencesAny(ICompiledAssembly compiledAssembly, params string[] assemblyNames)
{
return compiledAssembly.References.Any(reference => assemblyNames.Any(name =>
string.Equals(Path.GetFileNameWithoutExtension(reference), name, StringComparison.Ordinal)));
}
}
}