Пример #1
0
        private static bool CanShowInvalidAttributeErrorForMember(MemberInfo memberInfo, Type containedValueType, Type attrType)
        {
            if (memberInfo is MethodInfo)
            {
                return(false);
            }

            var memberValueType = memberInfo.GetReturnType();

            if (containedValueType == typeof(NoType) || memberValueType == typeof(object) || memberInfo.IsDefined <SuppressInvalidAttributeErrorAttribute>())
            {
                return(false);
            }

            var drawers = DrawerLocator.GetAttributeDrawers(attrType, containedValueType);

            if (drawers.Length > 0)
            {
                return(false);
            }

            if (memberValueType.ImplementsOpenGenericInterface(typeof(IList <>)))
            {
                Type listElementType = memberValueType.GetArgumentsOfInheritedOpenGenericInterface(typeof(IList <>))[0];

                if (listElementType == typeof(object))
                {
                    return(false);
                }

                drawers = DrawerLocator.GetAttributeDrawers(attrType, listElementType);

                if (drawers.Length > 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #2
0
        /// <summary>
        /// Get all primary value drawers for a given member info with a given contained value type.
        /// </summary>
        public static OdinDrawer[] GetDrawersForMemberInfo(MemberInfo memberInfo, Type containedValueType = null, bool isListElement = false)
        {
            if (containedValueType == null)
            {
                containedValueType = typeof(NoType);
            }

            if (memberInfo == null)
            {
                // This happens for Unity aliased properties
                memberInfo = NoMemberInfo;
            }

            OdinDrawer[] result;

            var cache = isListElement ? DrawerLocator.ListElementDrawerCache : DrawerLocator.MemberDrawerCache;

            if (!cache.TryGetInnerValue(memberInfo, containedValueType, out result))
            {
                List <OdinDrawer> resultList = new List <OdinDrawer>();

                // Find all possible attribute drawers
                foreach (var attribute in memberInfo.GetAttributes <Attribute>(true))
                {
                    var attrType = attribute.GetType();

                    if (isListElement && (attrType.IsDefined <DontApplyToListElementsAttribute>(true) || attrType.GetType() == typeof(UnityEngine.SpaceAttribute)))
                    {
                        continue;
                    }

                    var attrDrawers = DrawerLocator.GetAttributeDrawers(attrType, containedValueType, true);

                    if (attrDrawers.Length > 0)
                    {
                        resultList.AddRange(attrDrawers);
                    }
                    else if (!isListElement && CanShowInvalidAttributeErrorForMember(memberInfo, containedValueType, attrType))
                    {
                        List <DrawerInfo> validDrawers = new List <DrawerInfo>();

                        if (DrawerLocator.AttributeDrawerMap.ContainsKey(attrType))
                        {
                            validDrawers.AddRange(DrawerLocator.AttributeDrawerMap[attrType]);
                        }

                        if (validDrawers.Count > 0)
                        {
                            // Inject a drawer to state that this drawer-relevant attribute is invalid for the current value type
                            resultList.Add(new InvalidTypeForAttributeDrawer(memberInfo.GetNiceName(), attrType, containedValueType, validDrawers));
                        }
                    }
                }

                if (memberInfo is MethodInfo)
                {
                    // Add the standard method drawer
                    var drawer = GetDrawer(typeof(MethodPropertyDrawer <>).MakeGenericType(memberInfo.DeclaringType), false);
                    resultList.Add(drawer);
                }
                else
                {
                    // Add the standard value drawers
                    resultList.AddRange(DrawerLocator.GetValueDrawers(containedValueType));
                }

                // Sort all drawers by priority, and then order them by their original added order
                Dictionary <OdinDrawer, int> originalIndices = new Dictionary <OdinDrawer, int>(resultList.Count);

                for (int i = 0; i < resultList.Count; i++)
                {
                    originalIndices[resultList[i]] = i;
                }

                result = resultList.OrderByDescending(n => GetDrawerPriority(n.GetType()))
                         .ThenBy(n => originalIndices[n]).ToArray();

                cache.AddInner(memberInfo, containedValueType, result);
            }

            return(result);
        }