Skip to content

Commit

Permalink
feat: adding code gen extensions asmdef
Browse files Browse the repository at this point in the history
code gen base classes that can be shared by other asmdef other than the main weaver
  • Loading branch information
James-Frowen committed Jul 16, 2023
1 parent 7a2333d commit 1d7363d
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 2 deletions.
8 changes: 8 additions & 0 deletions Assets/Mirage/Weaver/Mirage.CecilExtensions.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Assets/Mirage/Weaver/Mirage.CecilExtensions/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Reflection;

[assembly: AssemblyVersion("0.1.0")]
11 changes: 11 additions & 0 deletions Assets/Mirage/Weaver/Mirage.CecilExtensions/AssemblyInfo.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Assets/Mirage/Weaver/Mirage.CecilExtensions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Mirage.Cecil

Extensions to help use Mono.Cecil inside Unity
7 changes: 7 additions & 0 deletions Assets/Mirage/Weaver/Mirage.CecilExtensions/README.md.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "Unity.Mirage.CecilExtensions.CodeGen",
"rootNamespace": "",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": true,
"precompiledReferences": [
"Mono.Cecil.dll",
"Mono.Cecil.Rocks.dll",
"Mono.Cecil.Mdb.dll",
"Mono.Cecil.Pdb.dll"
],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

119 changes: 119 additions & 0 deletions Assets/Mirage/Weaver/Mirage.CecilExtensions/WeaverBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Unity.CompilationPipeline.Common.Diagnostics;
using Unity.CompilationPipeline.Common.ILPostProcessing;

namespace Mirage.CodeGen
{
/// <summary>
/// Use as a base class for custom IL weaver. This class will read and write the AssemblyDefinition and return the results.
/// </summary>
public abstract class WeaverBase
{
public virtual string Name => this.GetType().FullName;

public readonly IWeaverLogger logger;

/// <summary>
/// Results from <see cref="Process(ICompiledAssembly)"/>
/// </summary>
public AssemblyDefinition AssemblyDefinition { get; private set; }

public WeaverBase(IWeaverLogger logger = null)
{
this.logger = logger ?? new WeaverLogger();
}

public enum Result
{
Success,
NoChanges,
Failed,
}

protected abstract Result Process(AssemblyDefinition assembly);

public ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
{
try
{
this.AssemblyDefinition = ReadAssembly(compiledAssembly);

var result = this.Process(this.AssemblyDefinition);

if (result == Result.Success)
return this.Success();
else if (result == Result.Failed)
return this.Failed();
else // no changes, no results
return null;
}
catch (Exception e)
{
// this means that Weaver had problems
// we should never get here unless there is a bug in the implementation
// for problems with user code, use logger instead of throwing so that multiple errors can be reported to the user.

return this.Error(e);
}
}

private ILPostProcessResult Success()
{
// write assembly to file on success
var pe = new MemoryStream();
var pdb = new MemoryStream();

var writerParameters = new WriterParameters
{
SymbolWriterProvider = new PortablePdbWriterProvider(),
SymbolStream = pdb,
WriteSymbols = true
};

this.AssemblyDefinition.Write(pe, writerParameters);
return new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), this.logger.GetDiagnostics());
}

private ILPostProcessResult Failed()
{
return new ILPostProcessResult(null, this.logger.GetDiagnostics());
}

private ILPostProcessResult Error(Exception e)
{
var message = new DiagnosticMessage
{
DiagnosticType = DiagnosticType.Error,
MessageData = $"Weaver {this.Name} failed on {this.AssemblyDefinition?.Name} because of Exception: {e}",
};
return new ILPostProcessResult(null, new List<DiagnosticMessage> { message });
}

private static AssemblyDefinition ReadAssembly(ICompiledAssembly compiledAssembly)
{
var assemblyResolver = new PostProcessorAssemblyResolver(compiledAssembly);
var readerParameters = new ReaderParameters
{
SymbolStream = new MemoryStream(compiledAssembly.InMemoryAssembly.PdbData),
SymbolReaderProvider = new PortablePdbReaderProvider(),
AssemblyResolver = assemblyResolver,
ReflectionImporterProvider = new PostProcessorReflectionImporterProvider(),
ReadingMode = ReadingMode.Immediate
};

var assemblyDefinition = AssemblyDefinition.ReadAssembly(new MemoryStream(compiledAssembly.InMemoryAssembly.PeData), readerParameters);

// apparently, it will happen that when we ask to resolve a type that lives inside the MyRuntime.asmdef, and we
// are also postprocessing MyRuntime.asmdef, type resolving will fail, because we do not actually try to resolve
// inside the assembly we are processing. Let's make sure we do that, so that we can use postprocessor features inside
// MyRuntime.asmdef itself as well.
assemblyResolver.AddAssemblyDefinitionBeingOperatedOn(assemblyDefinition);

return assemblyDefinition;
}
}
}
11 changes: 11 additions & 0 deletions Assets/Mirage/Weaver/Mirage.CecilExtensions/WeaverBase.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Assets/Mirage/Weaver/Unity.Mirage.CodeGen.asmdef
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{
"name": "Unity.Mirage.CodeGen",
"rootNamespace": "",
"references": [
"Mirage",
"UniTask"
"GUID:30817c1a0e6d646d99c048fc403f5979",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:f403fea27ba781d4790352849c7c1802"
],
"includePlatforms": [
"Editor"
Expand Down

0 comments on commit 1d7363d

Please sign in to comment.