public bool Equals(FlattenedItem item) { if (item == null) { return(false); } return(string.Equals(item.TypeFullName, TypeFullName, StringComparison.OrdinalIgnoreCase) && string.Equals(item.FlName, FlName, StringComparison.OrdinalIgnoreCase)); }
public virtual FlattenedItem FirstOnLeft(FlattenedItem searchItem) { if (Items == null) { return(null); } var searchIndex = Items.IndexOf(searchItem); return(searchIndex <= 0 ? null : Items[searchIndex - 1]); }
public virtual FlattenedItem FirstOnRight(FlattenedItem searchItem) { if (Items == null) { return(null); } var searchIndex = Items.IndexOf(searchItem); if (searchIndex < 0) { return(null); } return(searchIndex == Items.Count - 1 ? null : Items[searchIndex + 1]); }
public override FlattenedItem FirstOnRight(FlattenedItem searchItem) { return(_blank.FirstOrDefault()); }
//[EditorBrowsable(EditorBrowsableState.Never)] public static List <FlattenedLine> FlattenType(Assembly assembly, string typeFullName, ref int currentDepth, int maxDepth, string limitOnValueType, bool displayEnums, Stack <FlattenedItem> fiValueTypes, Stack typeStack) { var printList = new List <FlattenedLine>(); if (string.IsNullOrWhiteSpace(typeFullName)) { return(printList); } Func <PropertyInfo, string, bool> limitOnPi = (info, s) => string.IsNullOrWhiteSpace(s) || string.Equals($"{info.PropertyType}", s, StringComparison.OrdinalIgnoreCase) || string.Equals(NfReflect.GetLastTypeNameFromArrayAndGeneric(info.PropertyType), s, StringComparison.OrdinalIgnoreCase) || (s == Constants.ENUM && NfReflect.IsEnumType(info.PropertyType)); var currentType = assembly.NfGetType(typeFullName); if (currentType == null) { return(printList); } //top frame of recursive calls will perform this if (fiValueTypes == null) { if (maxDepth <= 0) { maxDepth = 16; } typeStack = new Stack(); typeStack.Push(typeFullName); fiValueTypes = new Stack <FlattenedItem>(); fiValueTypes.Push(new FlattenedItem(currentType) { FlName = NfReflect.GetTypeNameWithoutNamespace(typeFullName) }); } var typeNamesList = currentType.GetProperties(NfSettings.DefaultFlags) .Where( x => (NfReflect.IsValueTypeProperty(x) && limitOnPi(x, limitOnValueType) || (limitOnValueType == Constants.ENUM && limitOnPi(x, limitOnValueType))) //more limbo branching for enums ) .Select(p => new Tuple <Type, string>(p.PropertyType, p.Name)) .ToList(); foreach (var typeNamePair in typeNamesList) { var pVtype = typeNamePair.Item1; var pVname = typeNamePair.Item2; fiValueTypes.Push(new FlattenedItem(pVtype) { FlName = pVname }); var fiItems = fiValueTypes.ToList(); fiItems.Reverse(); printList.Add(new FlattenedLine(fiItems.Distinct(new FlattenedItemComparer()).ToList()) { ValueType = $"{typeNamePair.Item1}" }); fiValueTypes.Pop(); } //then recurse the object types foreach ( var p in currentType.GetProperties(NfSettings.DefaultFlags) .Where(x => !NfReflect.IsValueTypeProperty(x))) { currentDepth += 1; //time to go if (currentDepth >= maxDepth) { return(printList); } var typeIn = NfReflect.GetLastTypeNameFromArrayAndGeneric(p.PropertyType); if (typeIn == null || typeStack.Contains(typeIn)) { continue; } var fi = new FlattenedItem(p.PropertyType) { FlName = p.Name }; if (fiValueTypes.ToList().Any(x => x.FlType == p.PropertyType)) { continue; } fiValueTypes.Push(fi); typeStack.Push(typeIn); //enum types being handled as limbo between value type and ref type string[] enumVals; if (displayEnums && NfReflect.IsEnumType(p.PropertyType, out enumVals)) { foreach (var ev in enumVals) { fiValueTypes.Push(new FlattenedItem(typeof(Enum)) { FlName = ev }); var fiItems = fiValueTypes.ToList(); fiItems.Reverse(); printList.Add(new FlattenedLine(fiItems.Distinct(new FlattenedItemComparer()).ToList()) { ValueType = String.Empty }); fiValueTypes.Pop(); } } else { printList.AddRange(FlattenType(assembly, fi.TypeFullName, ref currentDepth, maxDepth, limitOnValueType, displayEnums, fiValueTypes, typeStack)); } fiValueTypes.Pop(); typeStack.Pop(); currentDepth -= 1; } return(printList); }