2025-09-17 16:40:02 -07:00

80 lines
2.5 KiB
C#

using AssetRipper.Assets.Metadata;
namespace AssetRipper.AssemblyDumper.Passes;
public static class Pass061_AddConstructors
{
private const MethodAttributes PublicInstanceConstructorAttributes =
MethodAttributes.Public |
MethodAttributes.HideBySig |
MethodAttributes.SpecialName |
MethodAttributes.RuntimeSpecialName;
private readonly static HashSet<GeneratedClassInstance> processed = new HashSet<GeneratedClassInstance>();
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private static ITypeDefOrRef AssetInfoRef;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public static void DoPass()
{
AssetInfoRef = SharedState.Instance.Importer.ImportType<AssetInfo>();
IEnumerable<ClassGroupBase> groups = SharedState.Instance.ClassGroups.Values.Select(g => (ClassGroupBase)g)
.Union(SharedState.Instance.SubclassGroups.Values.Select(g => (ClassGroupBase)g));
foreach (ClassGroupBase group in groups)
{
foreach (GeneratedClassInstance instance in group.Instances)
{
if (processed.Contains(instance))
{
continue;
}
AddConstructor(instance);
}
}
processed.Clear();
}
private static void AddConstructor(GeneratedClassInstance instance)
{
if (instance.Base is not null && !processed.Contains(instance.Base))
{
AddConstructor(instance.Base);
}
TypeDefinition type = instance.Type;
if (instance.Group is ClassGroup)
{
type.AddAssetInfoConstructor();
}
else
{
type.AddEmptyDefaultConstructor();
}
processed.Add(instance);
}
private static MethodDefinition AddAssetInfoConstructor(this TypeDefinition typeDefinition)
{
return AddSingleParameterConstructor(typeDefinition, AssetInfoRef, "info");
}
private static MethodDefinition AddEmptyDefaultConstructor(this TypeDefinition typeDefinition)
{
return typeDefinition.AddMethod(
".ctor",
PublicInstanceConstructorAttributes,
SharedState.Instance.Importer.Void
);
}
private static MethodDefinition AddSingleParameterConstructor(this TypeDefinition typeDefinition, ITypeDefOrRef parameterType, string parameterName)
{
MethodDefinition? constructor = typeDefinition.AddMethod(
".ctor",
PublicInstanceConstructorAttributes,
SharedState.Instance.Importer.Void
);
constructor.AddParameter(parameterType.ToTypeSignature(), parameterName);
return constructor;
}
}