Skip to content

Instantly share code, notes, and snippets.

@joelpryde
Created May 6, 2021 09:15
Show Gist options
  • Save joelpryde/d7c0c026b501e3102dd1d37af888ce1e to your computer and use it in GitHub Desktop.
Save joelpryde/d7c0c026b501e3102dd1d37af888ce1e to your computer and use it in GitHub Desktop.
#if SYSTEM_SOURCEGEN_ENABLED
using System.Linq;
using Mono.Cecil;
using Unity.Entities;
using Unity.Entities.CodeGen;
class Cloner : EntitiesILPostProcessor
{
protected override bool PostProcessImpl(TypeDefinition[] componentSystemTypes)
{
var madeChange = false;
foreach (var c in componentSystemTypes)
{
var typeMethods = c.Methods.ToArray();
foreach (var sourceMethod in typeMethods.Where(m => m.CustomAttributes.Any(
attribute => attribute.AttributeType.Name == nameof(DOTSCompilerPatchedMethodAttribute))))
{
var destinationMethodName = sourceMethod.CustomAttributes.First(attribute => attribute.AttributeType.Name == nameof(DOTSCompilerPatchedMethodAttribute))
.ConstructorArguments.First().Value.ToString();
var matchingMethods = c.Methods.Where(m => m.Name == destinationMethodName);
var destinationMethod = matchingMethods.Single();
foreach (var displayClass in destinationMethod.Body.Variables.Select(v => v.VariableType).OfType<TypeDefinition>().Where(IsDisplayClass))
destinationMethod.DeclaringType.NestedTypes.Remove(displayClass);
destinationMethod.Body = sourceMethod.Body;
c.Methods.Remove(sourceMethod);
var sequencePoints = destinationMethod.DebugInformation.SequencePoints;
sequencePoints.Clear();
foreach (var sp in sourceMethod.DebugInformation.SequencePoints)
sequencePoints.Add(sp);
destinationMethod.DebugInformation.Scope = sourceMethod.DebugInformation.Scope;
if (destinationMethod.HasGenericParameters && sourceMethod.HasGenericParameters)
{
destinationMethod.GenericParameters.Clear();
foreach (var genericSourceParam in sourceMethod.GenericParameters)
destinationMethod.GenericParameters.Add(genericSourceParam);
}
madeChange = true;
}
}
return madeChange;
}
static bool IsDisplayClass(TypeDefinition arg) => arg.Name.Contains("<>");
protected override bool PostProcessUnmanagedImpl(TypeDefinition[] unmanagedComponentSystemTypes)
{
return false;
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment