Пример #1
0
        /// <summary>
        /// This will check for conflicts when finding interface functions. If there is a conflict
        /// the code output is likely to be undesirable.
        /// </summary>
        private void ValidateNoInterfaceFunctionConflict(UClass unrealClass, UFunction function,
                                                         UClass skipInterface, bool skipSelf)
        {
            FName     functionName     = function.GetFName();
            UFunction conflictFunction = null;

            foreach (FImplementedInterface implementedInterface in unrealClass.Interfaces)
            {
                UClass interfaceClass = implementedInterface.InterfaceClass;
                if (interfaceClass != null && interfaceClass != skipInterface)
                {
                    if ((conflictFunction = interfaceClass.FindFunctionByName(functionName, true)) != null)
                    {
                        break;
                    }
                }
            }

            if (conflictFunction == null && !skipSelf)
            {
                conflictFunction = unrealClass.FindFunctionByName(functionName, false);
            }

            if (conflictFunction == null)
            {
                UClass parentClass = unrealClass.GetSuperClass();
                if (parentClass != null)
                {
                    // Search the rest of the hierarchy
                    conflictFunction = parentClass.FindFunctionByName(functionName, true);
                }
            }

            if (conflictFunction != null)
            {
                string warning = "Function redefined in hierarchy where interfaces are used. This is likely going to produce " +
                                 "unexpected results and should be avoided where possible. ImplementedInClass: '" + unrealClass.GetPathName() +
                                 "' InterfaceFunc: '" + function.GetPathName() + "' ConflictFunc: '" + conflictFunction.GetPathName() + "'";
                FMessage.Log(ELogVerbosity.Warning, warning, "USharp-CodeGenerator");
            }
        }
Пример #2
0
        /// <summary>
        /// Searches the class hierarchy to find the original owner of the given function (by function name)
        /// </summary>
        private UClass GetOriginalFunctionOwnerInternal(UFunction function, out UFunction originalFunction,
                                                        out bool isInterfaceImplementation)
        {
            // Interfaces really mess up this function. Two interfaces could potentially provide the same function
            // in the class hierarchy. Or a class up the chain could provide a function but also an interface with
            // the same function name could exist. None of this maps to C# well in terms of ensuring this is all handled
            // properly AND with name conflict resolution (which is what GetOriginalFunctionOwner is partially used for).
            // - We ALWAYS want use the first interface found with the same function name in order to produce valid C#.
            //   (even if this then technically isn't necessarily the original function / owner).
            // - We should log when we find this type of situation where there are functions are redefined in a
            //   class / interface combo (regular class:class conflict should be fine).
            // - TODO: Handle interface hierarchy

            FName functionName = function.GetFName();

            isInterfaceImplementation = false;

            originalFunction = function;
            UClass owner = function.GetOwnerClass();

            if (owner != null)
            {
                // First check the interfaces of THIS class.
                foreach (FImplementedInterface implementedInterface in owner.Interfaces)
                {
                    UClass interfaceClass = implementedInterface.InterfaceClass;
                    if (interfaceClass != null)
                    {
                        UFunction interfaceFunction = interfaceClass.FindFunctionByName(functionName, false);
                        if (interfaceFunction != null)
                        {
                            originalFunction = interfaceFunction;
                            ValidateNoInterfaceFunctionConflict(owner, originalFunction, interfaceClass, true);

                            // We found the original function directly within one of the implemented interfaces.
                            // This means the input function is an implementation for one of the interfaces.
                            isInterfaceImplementation = true;
                            return(interfaceClass);
                        }
                    }
                }

                UClass parentClass = owner.GetSuperClass();
                while (parentClass != null)
                {
                    // Check the interfaces of the parent class.
                    foreach (FImplementedInterface implementedInterface in parentClass.Interfaces)
                    {
                        UClass interfaceClass = implementedInterface.InterfaceClass;
                        if (interfaceClass != null)
                        {
                            UFunction interfaceFunction = interfaceClass.FindFunctionByName(functionName, false);
                            if (interfaceFunction != null)
                            {
                                originalFunction = interfaceFunction;
                                ValidateNoInterfaceFunctionConflict(parentClass, originalFunction, interfaceClass, false);
                                return(interfaceClass);
                            }
                        }
                    }

                    UFunction parentFunction = parentClass.FindFunctionByName(functionName, false);
                    if (parentFunction == null)
                    {
                        break;
                    }
                    originalFunction = parentFunction;
                    owner            = parentClass;
                    parentClass      = parentClass.GetSuperClass();
                }
            }
            return(owner);
        }