92 lines
2.8 KiB
C#
92 lines
2.8 KiB
C#
|
|
using System.Text.RegularExpressions;
|
|||
|
|
using Mono.Cecil;
|
|||
|
|
using UnrealSharpWeaver.Utilities;
|
|||
|
|
using PropertyUtilities = UnrealSharpWeaver.Utilities.PropertyUtilities;
|
|||
|
|
|
|||
|
|
namespace UnrealSharpWeaver.MetaData;
|
|||
|
|
|
|||
|
|
public partial class StructMetaData : TypeReferenceMetadata
|
|||
|
|
{
|
|||
|
|
public List<PropertyMetaData> Fields { get; set; }
|
|||
|
|
public StructFlags StructFlags { get; set; }
|
|||
|
|
|
|||
|
|
// Non-serialized for JSON
|
|||
|
|
public readonly bool IsBlittableStruct;
|
|||
|
|
// End non-serialized
|
|||
|
|
|
|||
|
|
public StructMetaData(TypeDefinition structDefinition) : base(structDefinition, TypeDefinitionUtilities.UStructAttribute)
|
|||
|
|
{
|
|||
|
|
Fields = new List<PropertyMetaData>();
|
|||
|
|
IsBlittableStruct = true;
|
|||
|
|
|
|||
|
|
|
|||
|
|
var backingFieldRegex = BackingFieldRegex();
|
|||
|
|
foreach (var field in structDefinition.Fields)
|
|||
|
|
{
|
|||
|
|
if (field.IsStatic)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!field.IsUProperty())
|
|||
|
|
{
|
|||
|
|
// Struct is not blittable if it has non-UProperty fields
|
|||
|
|
IsBlittableStruct = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PropertyMetaData property = new PropertyMetaData(field);
|
|||
|
|
|
|||
|
|
// If we match against a backing property field use the property name instead.
|
|||
|
|
var backingFieldMatch = backingFieldRegex.Match(field.Name);
|
|||
|
|
if (backingFieldMatch.Success)
|
|||
|
|
{
|
|||
|
|
string propertyName = backingFieldMatch.Groups[1].Value;
|
|||
|
|
property.Name = propertyName;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (property.IsInstancedReference)
|
|||
|
|
{
|
|||
|
|
StructFlags |= StructFlags.HasInstancedReference;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Fields.Add(property);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool isPlainOldData = true;
|
|||
|
|
foreach (var prop in Fields)
|
|||
|
|
{
|
|||
|
|
if (!prop.PropertyDataType.IsBlittable)
|
|||
|
|
{
|
|||
|
|
IsBlittableStruct = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!prop.PropertyDataType.IsPlainOldData)
|
|||
|
|
{
|
|||
|
|
isPlainOldData = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
StructFlags |= (StructFlags) GetFlags(structDefinition, "StructFlagsMapAttribute");
|
|||
|
|
|
|||
|
|
if (isPlainOldData)
|
|||
|
|
{
|
|||
|
|
StructFlags |= StructFlags.IsPlainOldData;
|
|||
|
|
StructFlags |= StructFlags.NoDestructor;
|
|||
|
|
StructFlags |= StructFlags.ZeroConstructor;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!IsBlittableStruct)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CustomAttribute structFlagsAttribute = new CustomAttribute(WeaverImporter.Instance.BlittableTypeConstructor);
|
|||
|
|
structDefinition.CustomAttributes.Add(structFlagsAttribute);
|
|||
|
|
|
|||
|
|
TryAddMetaData("BlueprintType", true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[GeneratedRegex("<([a-zA-Z$_][a-zA-Z0-9$_]*)>k__BackingField")]
|
|||
|
|
private static partial Regex BackingFieldRegex();
|
|||
|
|
}
|