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