Beispiel #1
0
 private bool IsBlittablePropertyType(UProperty property)
 {
     return(property.IsBlittableType ||
            (property.IsA <UObjectProperty>() && Settings.UObjectAsBlittableType) ||
            (property.IsA <UStructProperty>() && IsBlittableStructProperty(property as UStructProperty)));
 }
Beispiel #2
0
            public void ResolveCollapsedMembers()
            {
                if (IsInterface)
                {
                    // Interface shouldn't have any C# properties, leave everything as functions
                    ResolveNameConflicts();
                    return;
                }

                collapsedMembers.Clear();
                collapsedMembersByFunction.Clear();
                collapsedMembersByProperty.Clear();

                var getters = new Dictionary <UFunction, CodeGeneratorSettings.CollapsedMemberSettings>();
                var setters = new Dictionary <UFunction, CodeGeneratorSettings.CollapsedMemberSettings>();

                // Conflicts aren't resolved at this point. May have multiple functions for a given name.
                // - If there are conflicts avoid collapsing those functions.
                Dictionary <string, List <UFunction> > gettersByName = new Dictionary <string, List <UFunction> >();
                Dictionary <string, List <UFunction> > settersByName = new Dictionary <string, List <UFunction> >();

                foreach (UFunction function in exportableFunctions)
                {
                    string functionName = codeGenerator.GetFunctionName(function, false);

                    // 1 param either as return value or parameter and no return
                    if (function.NumParms == 1)
                    {
                        UProperty returnProperty = function.GetReturnProperty();
                        if (returnProperty != null)
                        {
                            // Getter
                            foreach (var collapsedSetting in codeGenerator.Settings.CollapsedMembers)
                            {
                                if (!string.IsNullOrEmpty(collapsedSetting.GetPrefix) &&
                                    functionName.StartsWith(collapsedSetting.GetPrefix) &&
                                    (!collapsedSetting.RequiresBool || returnProperty.IsA <UBoolProperty>()))
                                {
                                    getters.Add(function, collapsedSetting);

                                    string trimmedName = functionName.Substring(collapsedSetting.GetPrefix.Length);
                                    if (trimmedName.Length > 0)
                                    {
                                        List <UFunction> functions;
                                        if (!gettersByName.TryGetValue(trimmedName, out functions))
                                        {
                                            gettersByName.Add(trimmedName, functions = new List <UFunction>());
                                        }
                                        functions.Add(function);
                                    }
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // Setter
                            UProperty firstParam = function.GetFirstParam();
                            if (firstParam != null)
                            {
                                foreach (var collapsedSetting in codeGenerator.Settings.CollapsedMembers)
                                {
                                    if (!string.IsNullOrEmpty(collapsedSetting.SetPrefix) &&
                                        functionName.StartsWith(collapsedSetting.SetPrefix) &&
                                        (!collapsedSetting.RequiresBool || firstParam.IsA <UBoolProperty>()))
                                    {
                                        setters.Add(function, collapsedSetting);

                                        string trimmedName = functionName.Substring(collapsedSetting.GetPrefix.Length);
                                        if (trimmedName.Length > 0)
                                        {
                                            List <UFunction> functions;
                                            if (!settersByName.TryGetValue(trimmedName, out functions))
                                            {
                                                settersByName.Add(trimmedName, functions = new List <UFunction>());
                                            }
                                            functions.Add(function);
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                for (int i = 0; i < 2; i++)
                {
                    bool isGetter = i == 0;
                    Dictionary <string, List <UFunction> > collection = isGetter ? gettersByName : settersByName;

                    foreach (KeyValuePair <string, List <UFunction> > funcs in collection)
                    {
                        if (funcs.Value.Count != 1)
                        {
                            continue;
                        }

                        string    name   = funcs.Key;
                        UFunction getter = isGetter ? funcs.Value[0] : null;
                        UFunction setter = !isGetter ? funcs.Value[0] : null;
                        CodeGeneratorSettings.CollapsedMemberSettings settings = null;
                        UProperty paramOrRetValProperty = null;

                        Dictionary <string, List <UFunction> > otherCollection = isGetter ? settersByName : gettersByName;
                        List <UFunction> otherFuncs;
                        if (otherCollection.TryGetValue(funcs.Key, out otherFuncs))
                        {
                            if (otherFuncs.Count > 1)
                            {
                                // Other function has a conflict
                                continue;
                            }

                            if (isGetter)
                            {
                                setter = otherFuncs[0];
                            }
                            else
                            {
                                getter = otherFuncs[0];
                            }
                        }

                        if ((getter != null && collapsedMembersByFunction.ContainsKey(getter)) ||
                            (setter != null && collapsedMembersByFunction.ContainsKey(setter)))
                        {
                            continue;
                        }

                        if (getter != null && setter != null)
                        {
                            UProperty returnProperty = getter.GetReturnProperty();
                            UProperty firstParam     = setter.GetFirstParam();
                            if (returnProperty != null && firstParam != null && !returnProperty.SameType(firstParam))
                            {
                                // Property type mismatch on Get/Set functions
                                continue;
                            }
                        }

                        if (getter != null)
                        {
                            paramOrRetValProperty = getter.GetReturnProperty();
                            settings = getters[getter];
                        }
                        else if (setter != null)
                        {
                            paramOrRetValProperty = setter.GetFirstParam();
                            settings = setters[setter];
                        }

                        if (paramOrRetValProperty == null)
                        {
                            continue;
                        }

                        UProperty backingProperty           = null;
                        bool      backingPropertyExportable = false;

                        foreach (KeyValuePair <UProperty, string> property in exportableProperties)
                        {
                            if (name == codeGenerator.GetMemberName(property.Key, false, property.Value) &&
                                property.Key.SameType(paramOrRetValProperty))
                            {
                                if (backingProperty != null)
                                {
                                    // Skip conflicts
                                    continue;
                                }
                                backingProperty           = property.Key;
                                backingPropertyExportable = true;
                            }
                        }

                        if (backingProperty == null)
                        {
                            foreach (KeyValuePair <UProperty, string> property in nonExportableProperties)
                            {
                                if (name == codeGenerator.GetMemberName(property.Key, false, property.Value) &&
                                    property.Key.SameType(paramOrRetValProperty))
                                {
                                    if (backingProperty != null)
                                    {
                                        // Skip conflicts
                                        continue;
                                    }
                                    backingProperty           = property.Key;
                                    backingPropertyExportable = false;
                                }
                            }
                        }

                        if (getter == null && setter != null)
                        {
                            // SetXXX exists but there isn't a backing property or the backing property isn't
                            // exportable so there wouldn't be any way access the property. Leave the function
                            // as it is rather than creating a setter-only C# property unless the getter is injected.
                            if (backingProperty == null || (!backingPropertyExportable && !settings.InjectNonExportableProperty))
                            {
                                continue;
                            }
                            if (settings.SetRequiresGet)
                            {
                                continue;
                            }
                        }
                        else if (getter != null && setter == null)
                        {
                            if (settings.GetRequiresSet)
                            {
                                continue;
                            }
                        }

                        if ((getter != null && getter.HasAllFunctionFlags(EFunctionFlags.BlueprintEvent)) ||
                            (setter != null && setter.HasAnyFunctionFlags(EFunctionFlags.BlueprintEvent)))
                        {
                            // Skip events as they need a normal method body
                            continue;
                        }

                        string finalName = name;
                        if (!settings.StripPrefix && (getter == null || setter == null))
                        {
                            if (getter != null)
                            {
                                finalName = settings.GetPrefix + finalName;
                            }
                            else if (setter != null)
                            {
                                finalName = settings.SetPrefix + finalName;
                            }
                        }

                        if (backingProperty != null && backingProperty.HasAnyPropertyFlags(EPropertyFlags.BlueprintReadOnly) &&
                            IsCollectionProperty(backingProperty) && setter != null)
                        {
                            // If there is a backing property which is a readonly collection and there is a setter method then
                            // there will be type conflicts. Don't collapse them.
                            continue;
                        }

                        // Some validation on bool properties
                        {
                            UBoolProperty getterReturn = getter == null ? null : getter.GetReturnProperty() as UBoolProperty;
                            UBoolProperty setterParam  = setter == null ? null : setter.GetFirstParam() as UBoolProperty;

                            if (getterReturn != null && setterParam != null)
                            {
                                System.Diagnostics.Debug.Assert(getterReturn.ElementSize == setterParam.ElementSize,
                                                                "Get/Set use different bool size");
                            }

                            UBoolProperty backingBoolProperty = backingProperty as UBoolProperty;
                            if (backingBoolProperty != null)
                            {
                                if (getter != null)
                                {
                                    System.Diagnostics.Debug.Assert(backingBoolProperty.ElementSize == getterReturn.ElementSize,
                                                                    "BackingProperty/Get use different bool size");
                                }
                                else if (setter != null)
                                {
                                    System.Diagnostics.Debug.Assert(backingBoolProperty.ElementSize == setterParam.ElementSize,
                                                                    "BackingProperty/Set use different bool size");
                                }
                            }
                        }

                        CollapsedMember collapsedMember = new CollapsedMember(settings);
                        collapsedMember.BackingProperty             = backingProperty;
                        collapsedMember.IsBackingPropertyExportable = backingPropertyExportable;
                        collapsedMember.Getter   = getter;
                        collapsedMember.Setter   = setter;
                        collapsedMember.Name     = finalName;
                        collapsedMember.Property = paramOrRetValProperty;
                        collapsedMembers.Add(collapsedMember);
                        if (getter != null)
                        {
                            collapsedMembersByFunction.Add(getter, collapsedMember);
                        }
                        if (setter != null)
                        {
                            collapsedMembersByFunction.Add(setter, collapsedMember);
                        }
                        if (backingPropertyExportable)
                        {
                            collapsedMembersByProperty.Add(backingProperty, collapsedMember);
                        }
                    }
                }

                ResolveNameConflicts();
            }