428 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			428 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								using System;
							 | 
						|||
| 
								 | 
							
								using System.Collections.Generic;
							 | 
						|||
| 
								 | 
							
								using System.Linq;
							 | 
						|||
| 
								 | 
							
								using EpicGames.Core;
							 | 
						|||
| 
								 | 
							
								using EpicGames.UHT.Types;
							 | 
						|||
| 
								 | 
							
								using UnrealSharpScriptGenerator.Exporters;
							 | 
						|||
| 
								 | 
							
								using UnrealSharpScriptGenerator.PropertyTranslators;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace UnrealSharpScriptGenerator.Utilities;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								public class GetterSetterPair
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    public GetterSetterPair(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        PropertyName = property.GetPropertyName();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (!property.HasNativeGetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            UhtFunction? foundGetter = property.GetBlueprintGetter();
							 | 
						|||
| 
								 | 
							
								            if (foundGetter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                Getter = foundGetter;
							 | 
						|||
| 
								 | 
							
								                GetterExporter = GetterSetterFunctionExporter.Create(foundGetter, property, GetterSetterMode.Get,
							 | 
						|||
| 
								 | 
							
								                    EFunctionProtectionMode.UseUFunctionProtection);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (!property.HasNativeSetter())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            UhtFunction? foundSetter = property.GetBlueprintSetter();
							 | 
						|||
| 
								 | 
							
								            if (foundSetter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                Setter = foundSetter;
							 | 
						|||
| 
								 | 
							
								                SetterExporter = GetterSetterFunctionExporter.Create(foundSetter, property, GetterSetterMode.Set,
							 | 
						|||
| 
								 | 
							
								                    EFunctionProtectionMode.UseUFunctionProtection);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public GetterSetterPair(string propertyName)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        PropertyName = propertyName;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public readonly string PropertyName;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public UhtFunction? Getter { get; set; }
							 | 
						|||
| 
								 | 
							
								    public UhtFunction? Setter { get; set; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public GetterSetterFunctionExporter? GetterExporter { get; set; }
							 | 
						|||
| 
								 | 
							
								    public GetterSetterFunctionExporter? SetterExporter { get; set; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public List<UhtFunction> Accessors
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        get
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            List<UhtFunction> accessors = new();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            UhtFunction? getter = Getter;
							 | 
						|||
| 
								 | 
							
								            if (getter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                accessors.Add(getter);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            UhtFunction? setter = Setter;
							 | 
						|||
| 
								 | 
							
								            if (setter != null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                accessors.Add(setter);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            return accessors;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public UhtProperty? Property { get; set; }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								public static class ScriptGeneratorUtilities
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    public const string InteropNamespace = "UnrealSharp.Interop";
							 | 
						|||
| 
								 | 
							
								    public const string MarshallerNamespace = "UnrealSharp.Core.Marshallers";
							 | 
						|||
| 
								 | 
							
								    public const string AttributeNamespace = "UnrealSharp.Attributes";
							 | 
						|||
| 
								 | 
							
								    public const string CoreAttributeNamespace = "UnrealSharp.Core.Attributes";
							 | 
						|||
| 
								 | 
							
								    public const string InteropServicesNamespace = "System.Runtime.InteropServices";
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public const string PublicKeyword = "public ";
							 | 
						|||
| 
								 | 
							
								    public const string PrivateKeyword = "private ";
							 | 
						|||
| 
								 | 
							
								    public const string ProtectedKeyword = "protected ";
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								    public const string IntPtrZero = "IntPtr.Zero";
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static string TryGetPluginDefine(string key)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        Program.PluginModule.TryGetDefine(key, out string? generatedCodePath);
							 | 
						|||
| 
								 | 
							
								        return generatedCodePath!;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static bool CanExportFunction(UhtFunction function)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (function.HasAnyFlags(EFunctionFlags.Delegate | EFunctionFlags.MulticastDelegate))
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        return CanExportParameters(function);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static bool CanExportParameters(UhtFunction function)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        bool CanExportParameter(UhtProperty property, Func<PropertyTranslator, bool> isSupported)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            PropertyTranslator? translator = PropertyTranslatorManager.GetTranslator(property);
							 | 
						|||
| 
								 | 
							
								            return translator != null && isSupported(translator) && translator.CanExport(property);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (function.ReturnProperty != null && !CanExportParameter(function.ReturnProperty,
							 | 
						|||
| 
								 | 
							
								                translator => translator.IsSupportedAsReturnValue()))
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        foreach (UhtProperty parameter in function.Properties)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (!CanExportParameter(parameter, translator => translator.IsSupportedAsParameter()))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                return false;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        return true;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static bool CanExportProperty(UhtProperty property)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        PropertyTranslator? translator = PropertyTranslatorManager.GetTranslator(property);
							 | 
						|||
| 
								 | 
							
								        if (translator == null || !translator.CanExport(property))
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        bool isClassProperty = property.Outer!.EngineType == UhtEngineType.Class;
							 | 
						|||
| 
								 | 
							
								        bool canBeClassProperty = isClassProperty && translator.IsSupportedAsProperty();
							 | 
						|||
| 
								 | 
							
								        bool canBeStructProperty = !isClassProperty && translator.IsSupportedAsStructProperty();
							 | 
						|||
| 
								 | 
							
								        return canBeClassProperty || canBeStructProperty;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static string GetCleanEnumValueName(UhtEnum enumObj, UhtEnumValue enumValue)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (enumObj.CppForm == UhtEnumCppForm.Regular)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return enumValue.Name;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        int delimiterIndex = enumValue.Name.IndexOf("::", StringComparison.Ordinal);
							 | 
						|||
| 
								 | 
							
								        return delimiterIndex < 0 ? enumValue.Name : enumValue.Name.Substring(delimiterIndex + 2);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static void GetExportedProperties(UhtStruct structObj, List<UhtProperty> properties,
							 | 
						|||
| 
								 | 
							
								        Dictionary<UhtProperty, GetterSetterPair> getterSetterBackedProperties)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        if (!structObj.Properties.Any())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        UhtClass? classObj = structObj as UhtClass;
							 | 
						|||
| 
								 | 
							
								        foreach (UhtProperty property in structObj.Properties)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (!CanExportProperty(property) || InclusionLists.HasBannedProperty(property))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                continue;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if (classObj != null && (property.HasAnyGetter() || property.HasAnySetter()))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                GetterSetterPair pair = new GetterSetterPair(property);
							 | 
						|||
| 
								 | 
							
								                getterSetterBackedProperties.Add(property, pair);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            else
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                properties.Add(property);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static void GetExportedFunctions(UhtClass classObj, List<UhtFunction> functions,
							 | 
						|||
| 
								 | 
							
								                                            List<UhtFunction> overridableFunctions,
							 | 
						|||
| 
								 | 
							
								                                            Dictionary<string, GetterSetterPair> getterSetterPairs,
							 | 
						|||
| 
								 | 
							
								                                            Dictionary<string, GetterSetterPair> getSetOverrides)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        List<UhtFunction> exportedFunctions = new();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        bool HasFunction(List<UhtFunction> functionsToCheck, UhtFunction functionToTest)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            foreach (UhtFunction function in functionsToCheck)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                if (function.SourceName == functionToTest.SourceName ||
							 | 
						|||
| 
								 | 
							
								                    function.CppImplName == functionToTest.CppImplName)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    return true;
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        foreach (UhtFunction function in classObj.Functions)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (!CanExportFunction(function))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                continue;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if (function.IsAnyGetter() || function.IsAnySetter())
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                continue;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if (function.FunctionFlags.HasAnyFlags(EFunctionFlags.BlueprintEvent))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                overridableFunctions.Add(function);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            else if (function.IsAutocast())
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                functions.Add(function);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                if (function.Properties.First() is not UhtStructProperty structToConvertProperty)
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    continue;
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                if (structToConvertProperty.Package.IsPartOfEngine() != function.Package.IsPartOfEngine())
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    // For auto-casts to work, they both need to be in the same generated assembly. 
							 | 
						|||
| 
								 | 
							
								                    // Currently not supported, as we separate engine and project generated assemblies.
							 | 
						|||
| 
								 | 
							
								                    continue;
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                AutocastExporter.AddAutocastFunction(structToConvertProperty.ScriptStruct, function);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            else if (!TryMakeFunctionGetterSetterPair(function, classObj, getterSetterPairs, false))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                functions.Add(function);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            exportedFunctions.Add(function);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        foreach (UhtClass declaration in classObj.GetInterfaces())
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            UhtClass? interfaceClass = declaration.GetInterfaceAlternateClass();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if (interfaceClass == null)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                continue;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            foreach (UhtFunction function in interfaceClass.Functions)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                if (TryMakeFunctionGetterSetterPair(function, interfaceClass, getSetOverrides, true) 
							 | 
						|||
| 
								 | 
							
								                    || HasFunction(exportedFunctions, function) || !CanExportFunction(function))
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    continue;
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                if (function.FunctionFlags.HasAnyFlags(EFunctionFlags.BlueprintEvent))
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    overridableFunctions.Add(function);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                else
							 | 
						|||
| 
								 | 
							
								                {
							 | 
						|||
| 
								 | 
							
								                    functions.Add(function);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static List<UhtClass> GetInterfaces(this UhtClass classObj)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        List<UhtClass> interfaces = new();
							 | 
						|||
| 
								 | 
							
								        foreach (UhtStruct interfaceClass in classObj.Bases)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            UhtEngineType engineType = interfaceClass.EngineType;
							 | 
						|||
| 
								 | 
							
								            if (engineType is UhtEngineType.Interface or UhtEngineType.NativeInterface)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                interfaces.Add((UhtClass)interfaceClass);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        return interfaces;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static bool TryMakeFunctionGetterSetterPair(UhtFunction function, UhtClass classObj,
							 | 
						|||
| 
								 | 
							
								        Dictionary<string, GetterSetterPair> getterSetterPairs, bool ignoreMatchingProperty)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        string scriptName = function.GetFunctionName();
							 | 
						|||
| 
								 | 
							
								        bool isGetter = CheckIfGetter(scriptName, function);
							 | 
						|||
| 
								 | 
							
								        bool isSetter = CheckIfSetter(scriptName, function);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (!isGetter && !isSetter)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        string propertyName = scriptName.Length > 3 ? scriptName.Substring(3) : function.SourceName;
							 | 
						|||
| 
								 | 
							
								        propertyName = NameMapper.EscapeKeywords(propertyName);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        UhtFunction? sameNameFunction = classObj.FindFunctionByName(propertyName);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (sameNameFunction != null && sameNameFunction != function)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        bool ComparePropertyName(UhtProperty prop, string name)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return prop.SourceName == name || prop.GetPropertyName() == name;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        UhtProperty? classProperty = !ignoreMatchingProperty ? classObj.FindPropertyByName(propertyName, ComparePropertyName) : null;
							 | 
						|||
| 
								 | 
							
								        UhtProperty firstProperty = function.ReturnProperty ?? function.Properties.First();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (classProperty != null && (!classProperty.IsSameType(firstProperty) || classProperty.HasAnyGetter() ||
							 | 
						|||
| 
								 | 
							
								                                      classProperty.HasAnySetter()))
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (!getterSetterPairs.TryGetValue(propertyName, out GetterSetterPair? pair))
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            pair = new GetterSetterPair(propertyName);
							 | 
						|||
| 
								 | 
							
								            getterSetterPairs[propertyName] = pair;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (pair.Accessors.Count == 2)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return true;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        bool isOutParm = function.Properties.Any(p =>
							 | 
						|||
| 
								 | 
							
								            p.HasAllFlags(EPropertyFlags.OutParm) && !p.HasAllFlags(EPropertyFlags.ConstParm));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (function.ReturnProperty != null || isOutParm)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            pair.Getter = function;
							 | 
						|||
| 
								 | 
							
								            // When creating the getter, bind it to the getter's own value type (return or out param)
							 | 
						|||
| 
								 | 
							
								            UhtProperty getterValueProperty = function.ReturnProperty ?? function.Properties.First(p =>
							 | 
						|||
| 
								 | 
							
								                p.HasAllFlags(EPropertyFlags.OutParm) && !p.HasAllFlags(EPropertyFlags.ConstParm));
							 | 
						|||
| 
								 | 
							
								            pair.GetterExporter = GetterSetterFunctionExporter.Create(function, getterValueProperty, GetterSetterMode.Get,
							 | 
						|||
| 
								 | 
							
								                EFunctionProtectionMode.UseUFunctionProtection);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            UhtFunction? setter = classObj.FindFunctionByName("Set" + propertyName, null, true);
							 | 
						|||
| 
								 | 
							
								            if (setter != null && CheckIfSetter(setter))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                pair.Setter = setter;
							 | 
						|||
| 
								 | 
							
								                // Keep using the getter's value type as the canonical property type
							 | 
						|||
| 
								 | 
							
								                pair.SetterExporter = GetterSetterFunctionExporter.Create(setter, getterValueProperty, GetterSetterMode.Set,
							 | 
						|||
| 
								 | 
							
								                    EFunctionProtectionMode.UseUFunctionProtection);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            pair.Setter = function;
							 | 
						|||
| 
								 | 
							
								            pair.SetterExporter = GetterSetterFunctionExporter.Create(function, firstProperty, GetterSetterMode.Set,
							 | 
						|||
| 
								 | 
							
								                EFunctionProtectionMode.UseUFunctionProtection);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            UhtFunction? getter = classObj.FindFunctionByName("Get" + propertyName, null, true);
							 | 
						|||
| 
								 | 
							
								            if (getter != null && CheckIfGetter(getter))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                pair.Getter = getter;
							 | 
						|||
| 
								 | 
							
								                // Prefer the getter's own value type (return or out param) for the property type
							 | 
						|||
| 
								 | 
							
								                UhtProperty getterValueProperty = getter.ReturnProperty ?? getter.Properties.First(p =>
							 | 
						|||
| 
								 | 
							
								                    p.HasAllFlags(EPropertyFlags.OutParm) && !p.HasAllFlags(EPropertyFlags.ConstParm));
							 | 
						|||
| 
								 | 
							
								                pair.GetterExporter = GetterSetterFunctionExporter.Create(getter, getterValueProperty, GetterSetterMode.Get,
							 | 
						|||
| 
								 | 
							
								                    EFunctionProtectionMode.UseUFunctionProtection);
							 | 
						|||
| 
								 | 
							
								                // Also re-bind the setter exporter to the getter's value type so signatures align
							 | 
						|||
| 
								 | 
							
								                pair.SetterExporter = GetterSetterFunctionExporter.Create(function, getterValueProperty, GetterSetterMode.Set,
							 | 
						|||
| 
								 | 
							
								                    EFunctionProtectionMode.UseUFunctionProtection);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        // Canonical property type: prefer getter value type when available, else fall back to current function's type
							 | 
						|||
| 
								 | 
							
								        if (pair.Getter != null)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            pair.Property = pair.Getter.ReturnProperty ?? pair.Getter.Properties.First(p =>
							 | 
						|||
| 
								 | 
							
								                p.HasAllFlags(EPropertyFlags.OutParm) && !p.HasAllFlags(EPropertyFlags.ConstParm));
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        else
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            pair.Property = firstProperty;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        getterSetterPairs[propertyName] = pair;
							 | 
						|||
| 
								 | 
							
								        return true;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    static bool CheckIfGetter(string scriptName, UhtFunction function)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        return scriptName.StartsWith("Get") && CheckIfGetter(function);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    static bool CheckIfGetter(UhtFunction function)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        int childrenCount = function.Children.Count;
							 | 
						|||
| 
								 | 
							
								        bool hasReturnProperty = function.ReturnProperty != null;
							 | 
						|||
| 
								 | 
							
								        bool hasNoParameters = !function.HasParameters;
							 | 
						|||
| 
								 | 
							
								        bool hasSingleOutParam = !hasNoParameters && childrenCount == 1 && function.HasOutParams();
							 | 
						|||
| 
								 | 
							
								        bool hasWorldContextPassParam =
							 | 
						|||
| 
								 | 
							
								            childrenCount == 2 && function.Properties.Any(property => property.IsWorldContextParameter());
							 | 
						|||
| 
								 | 
							
								        bool isNotBlueprintEvent = !function.FunctionFlags.HasAnyFlags(EFunctionFlags.BlueprintEvent);
							 | 
						|||
| 
								 | 
							
								        return hasReturnProperty && isNotBlueprintEvent && (hasNoParameters || hasSingleOutParam || hasWorldContextPassParam);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    static bool CheckIfSetter(string scriptName, UhtFunction function)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        return scriptName.StartsWith("Set") && CheckIfSetter(function);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    static bool CheckIfSetter(UhtFunction function)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        bool hasSingleParameter = function.Properties.Count() == 1;
							 | 
						|||
| 
								 | 
							
								        var property = function.Properties.FirstOrDefault();
							 | 
						|||
| 
								 | 
							
								        bool isNotOutOrReferenceParam = function.HasParameters && property is not null 
							 | 
						|||
| 
								 | 
							
								                                                               && (!property.HasAllFlags(EPropertyFlags.OutParm | EPropertyFlags.ReferenceParm) 
							 | 
						|||
| 
								 | 
							
								                                                                   || property.HasAllFlags(EPropertyFlags.ConstParm));
							 | 
						|||
| 
								 | 
							
								        bool isNotBlueprintEvent = !function.FunctionFlags.HasAnyFlags(EFunctionFlags.BlueprintEvent);
							 | 
						|||
| 
								 | 
							
								        return hasSingleParameter && isNotBlueprintEvent && isNotOutOrReferenceParam;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |