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();
 | |
| } |