199 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Collections.Generic;
 | |
| using System.IO;
 | |
| using System.Linq;
 | |
| using EpicGames.Core;
 | |
| using EpicGames.UHT.Types;
 | |
| using UnrealSharpScriptGenerator.PropertyTranslators;
 | |
| using UnrealSharpScriptGenerator.Tooltip;
 | |
| using UnrealSharpScriptGenerator.Utilities;
 | |
| 
 | |
| namespace UnrealSharpScriptGenerator.Exporters;
 | |
| 
 | |
| public static class ClassExporter
 | |
| {
 | |
|     public static void ExportClass(UhtClass classObj, bool isManualExport)
 | |
|     {
 | |
|         GeneratorStringBuilder stringBuilder = new();
 | |
| 
 | |
|         string typeNameSpace = classObj.GetNamespace();
 | |
|         
 | |
|         List<UhtFunction> exportedFunctions = new();
 | |
|         List<UhtFunction> exportedOverrides = new();
 | |
|         Dictionary<string, GetterSetterPair> exportedGetterSetters = new();
 | |
|         Dictionary<string, GetterSetterPair> getSetOverrides = new();
 | |
|         
 | |
|         ScriptGeneratorUtilities.GetExportedFunctions(classObj, exportedFunctions, 
 | |
|             exportedOverrides, 
 | |
|             exportedGetterSetters, getSetOverrides);
 | |
|         
 | |
|         List<UhtProperty> exportedProperties = new List<UhtProperty>();
 | |
|         Dictionary<UhtProperty, GetterSetterPair> getSetBackedProperties = new();
 | |
|         ScriptGeneratorUtilities.GetExportedProperties(classObj, exportedProperties, getSetBackedProperties);
 | |
|         
 | |
|         List<UhtClass> interfaces = classObj.GetInterfaces();
 | |
|         
 | |
|         bool nullableEnabled = classObj.HasMetadata(UhtTypeUtilities.NullableEnable);
 | |
|         stringBuilder.GenerateTypeSkeleton(typeNameSpace, nullableEnabled: nullableEnabled);
 | |
|         stringBuilder.AppendTooltip(classObj);
 | |
|         
 | |
|         AttributeBuilder attributeBuilder = new AttributeBuilder(classObj);
 | |
|         if (classObj.ClassFlags.HasAnyFlags(EClassFlags.Abstract))
 | |
|         {
 | |
|             attributeBuilder.AddArgument("ClassFlags.Abstract");
 | |
|         }
 | |
|         attributeBuilder.AddGeneratedTypeAttribute(classObj);
 | |
|         attributeBuilder.Finish();
 | |
|         stringBuilder.AppendLine(attributeBuilder.ToString());
 | |
| 
 | |
|         string superClassName;
 | |
|         if (classObj.SuperClass != null)
 | |
|         {
 | |
|             superClassName = classObj.SuperClass.GetFullManagedName();
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             superClassName = "UnrealSharp.Core.UnrealSharpObject";
 | |
|         }
 | |
|         
 | |
|         stringBuilder.DeclareType(classObj, "class", classObj.GetStructName(), superClassName, nativeInterfaces: interfaces);
 | |
|         
 | |
|         // For manual exports we just want to generate attributes
 | |
|         if (!isManualExport)
 | |
|         { 
 | |
|             StaticConstructorUtilities.ExportStaticConstructor(stringBuilder, classObj, 
 | |
|                 exportedProperties, 
 | |
|                 exportedFunctions, 
 | |
|                 exportedGetterSetters,
 | |
|                 getSetBackedProperties,
 | |
|                 exportedOverrides);
 | |
|             
 | |
|             HashSet<string> exportedPropertyNames = new();
 | |
|             HashSet<string> exportedFunctionNames = new();
 | |
|             ExportClassProperties(stringBuilder, exportedProperties, exportedPropertyNames);
 | |
|             ExportGetSetProperties(stringBuilder, getSetBackedProperties, exportedPropertyNames, exportedFunctionNames);
 | |
|             ExportCustomProperties(stringBuilder, exportedGetterSetters, exportedPropertyNames, exportedFunctionNames);
 | |
|             
 | |
|             ExportClassFunctions(classObj, stringBuilder, exportedFunctions, exportedFunctionNames);
 | |
|             ExportGetSetOverrides(stringBuilder, getSetOverrides, exportedPropertyNames, exportedFunctionNames);
 | |
|             ExportOverrides(stringBuilder, exportedOverrides, exportedFunctionNames);
 | |
|             stringBuilder.AppendLine();
 | |
|         }
 | |
| 
 | |
|         stringBuilder.CloseBrace();
 | |
|         
 | |
|         FileExporter.SaveGlueToDisk(classObj, stringBuilder);
 | |
|     }
 | |
| 
 | |
|     static void ExportClassProperties(GeneratorStringBuilder generatorStringBuilder, List<UhtProperty> exportedProperties, HashSet<string> exportedPropertyNames)
 | |
|     {
 | |
|         foreach (UhtProperty property in exportedProperties)
 | |
|         {
 | |
|             PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(property)!;
 | |
|             translator.ExportProperty(generatorStringBuilder, property);
 | |
|             exportedPropertyNames.Add(property.SourceName);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     public static void ExportGetSetProperties(GeneratorStringBuilder builder, 
 | |
|                                               Dictionary<UhtProperty, GetterSetterPair> getSetBackedProperties, 
 | |
|                                               HashSet<string> exportedPropertyNames,
 | |
|                                               HashSet<string> exportedFunctionNames)
 | |
|     {
 | |
|         Dictionary<UhtFunction, FunctionExporter> exportedGetterSetters = new();
 | |
|         foreach (KeyValuePair<UhtProperty, GetterSetterPair> pair in getSetBackedProperties)
 | |
|         {
 | |
|             UhtProperty property = pair.Key;
 | |
|             GetterSetterPair getterSetterPair = pair.Value;
 | |
|             PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(property)!;
 | |
|             translator.ExportGetSetProperty(builder, getterSetterPair, property, exportedGetterSetters, exportedFunctionNames);
 | |
|             
 | |
|             exportedPropertyNames.Add(getterSetterPair.PropertyName);
 | |
|             foreach (UhtFunction function in getterSetterPair.Accessors)
 | |
|             {
 | |
|                 exportedFunctionNames.Add(function.SourceName);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private static void ExportGetSetOverrides(GeneratorStringBuilder builder, Dictionary<string, GetterSetterPair> getSetBackedProperties, 
 | |
|                                               HashSet<string> exportedPropertyNames, HashSet<string> exportedFunctionNames)
 | |
|     {
 | |
|         foreach (KeyValuePair<string, GetterSetterPair> pair in getSetBackedProperties)
 | |
|         {
 | |
|             if (pair.Value.Property == null)
 | |
|             {
 | |
|                 throw new InvalidDataException($"Property '{pair.Value.PropertyName}' does not have a UProperty");
 | |
|             }
 | |
|             
 | |
|             UhtFunction firstAccessor = pair.Value.Accessors.First();
 | |
|             UhtProperty firstProperty = pair.Value.Property;
 | |
|             string propertyName = pair.Value.PropertyName;
 | |
|             
 | |
|             PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(firstProperty)!;
 | |
|             builder.TryAddWithEditor(firstAccessor);
 | |
|             translator.ExportCustomProperty(builder, pair.Value, propertyName, firstProperty, 
 | |
|                 exportedPropertyNames.Contains(propertyName), exportedFunctionNames);
 | |
|             builder.TryEndWithEditor(firstAccessor);
 | |
|             
 | |
|             exportedPropertyNames.Add(propertyName);
 | |
|             foreach (UhtFunction function in pair.Value.Accessors)
 | |
|             {
 | |
|                 exportedFunctionNames.Add(function.SourceName);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     static void ExportOverrides(GeneratorStringBuilder builder, List<UhtFunction> exportedOverrides, HashSet<string> exportedFunctionNames)
 | |
|     {
 | |
|         foreach (UhtFunction function in exportedOverrides)
 | |
|         {
 | |
|             FunctionExporter.ExportOverridableFunction(builder, function, exportedFunctionNames);
 | |
|             exportedFunctionNames.Add(function.SourceName);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     static void ExportClassFunctions(UhtClass owner, GeneratorStringBuilder builder, List<UhtFunction> exportedFunctions,
 | |
|                                      HashSet<string> exportedFunctionNames)
 | |
|     {
 | |
|         bool isBlueprintFunctionLibrary = owner.IsChildOf(Program.BlueprintFunctionLibrary);
 | |
|         foreach (UhtFunction function in exportedFunctions)
 | |
|         {
 | |
|             if (function.HasAllFlags(EFunctionFlags.Static) && isBlueprintFunctionLibrary)
 | |
|             {
 | |
|                 FunctionExporter.TryAddExtensionMethod(function);
 | |
|             }
 | |
|             
 | |
|             FunctionExporter.ExportFunction(builder, function, FunctionType.Normal, exportedFunctionNames);
 | |
|             exportedFunctionNames.Add(function.SourceName);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static void ExportCustomProperties(GeneratorStringBuilder builder, 
 | |
|                                               Dictionary<string, GetterSetterPair> exportedGetterSetters, 
 | |
|                                               HashSet<string> exportedPropertyNames,
 | |
|                                               HashSet<string> exportedFunctionNames)
 | |
|     {
 | |
|         foreach (KeyValuePair<string, GetterSetterPair> pair in exportedGetterSetters)
 | |
|         {
 | |
|             if (pair.Value.Property == null)
 | |
|             {
 | |
|                 throw new InvalidDataException($"Property '{pair.Value.PropertyName}' does not have a UProperty");
 | |
|             }
 | |
|             
 | |
|             UhtFunction firstAccessor = pair.Value.Accessors.First();
 | |
|             UhtProperty firstProperty = pair.Value.Property;
 | |
|             string propertyName = pair.Value.PropertyName;
 | |
|             
 | |
|             PropertyTranslator translator = PropertyTranslatorManager.GetTranslator(firstProperty)!;
 | |
|             builder.TryAddWithEditor(firstAccessor);
 | |
|             translator.ExportCustomProperty(builder, pair.Value, propertyName, firstProperty, exportedFunctionNames: exportedFunctionNames);
 | |
|             builder.TryEndWithEditor(firstAccessor);
 | |
|             
 | |
|             exportedPropertyNames.Add(propertyName);
 | |
|             foreach (UhtFunction function in pair.Value.Accessors)
 | |
|             {
 | |
|                 exportedFunctionNames.Add(function.SourceName);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } |