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