feat: extract shared Cecil weaving core
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user