public TypeHierarchyItem LoadInterfaceHierarchy() { var interfaceRoot = new TypeHierarchyItem(null); if (Interfaces.Any()) { var rootInterfaces = new List <TypeHierarchyItem>(); for (int i = Interfaces.Length - 1; i >= 0; i--) { if (IsRootInterface(Interfaces[i].Symbol)) { rootInterfaces.Add(Interfaces[i]); } } FillHierarchyItems(rootInterfaces, interfaceRoot, FillHierarchyItem); } return(interfaceRoot); bool IsRootInterface(INamedTypeSymbol interfaceSymbol) { foreach (INamedTypeSymbol interfaceSymbol2 in interfaceSymbol.Interfaces) { foreach (TypeHierarchyItem interfaceItem in Interfaces) { if (interfaceItem.Symbol == interfaceSymbol2) { return(false); } } } return(true); } TypeHierarchyItem FillHierarchyItem(TypeHierarchyItem item, TypeHierarchyItem parent) { INamedTypeSymbol symbol = item.Symbol; item = new TypeHierarchyItem(symbol) { Parent = parent }; TypeHierarchyItem[] derivedInterfaces = Interfaces .Where(f => f.Symbol.Interfaces.Any(i => MetadataNameEqualityComparer <INamedTypeSymbol> .Instance.Equals(i.OriginalDefinition, symbol.OriginalDefinition))) .ToArray(); if (derivedInterfaces.Length > 0) { Array.Reverse(derivedInterfaces); FillHierarchyItems(derivedInterfaces, item, FillHierarchyItem); } return(item); } }
internal IEnumerable <TypeHierarchyItem> GetAncestors(bool self) { TypeHierarchyItem c = ((self) ? this : Parent); while (c != null) { yield return(c); c = c.Parent; } }
public IEnumerable <TypeHierarchyItem> Children() { TypeHierarchyItem e = content; if (e != null) { do { e = e.next; yield return(e); } while (e.Parent == this && e != content); } }
internal IEnumerable <TypeHierarchyItem> GetDescendants(bool self) { var e = this; if (self) { yield return(e); } var c = this; while (true) { TypeHierarchyItem first = c?.content?.next; if (first != null) { e = first; } else { while (e != this && e == e.Parent.content) { e = e.Parent; } if (e == this) { break; } e = e.next; } if (e != null) { yield return(e); } c = e; } }
private static void FillHierarchyItems( IList <TypeHierarchyItem> items, TypeHierarchyItem parent, Func <TypeHierarchyItem, TypeHierarchyItem, TypeHierarchyItem> fillHierarchyItem) { TypeHierarchyItem last = fillHierarchyItem(items[0], parent); TypeHierarchyItem next = last; TypeHierarchyItem child = null; for (int i = 1; i < items.Count; i++) { child = fillHierarchyItem(items[i], parent); child.next = next; next = child; } last.next = child ?? last; parent.content = last; }
public static TypeHierarchy Create(IEnumerable <INamedTypeSymbol> types, IComparer <INamedTypeSymbol> comparer = null) { if (comparer == null) { comparer = SymbolDefinitionComparer.SystemFirst.TypeComparer; } INamedTypeSymbol objectType = FindObjectType(); if (objectType == null) { throw new InvalidOperationException("Object type not found."); } Dictionary <INamedTypeSymbol, TypeHierarchyItem> allItems = types .ToDictionary(f => f, f => new TypeHierarchyItem(f), MetadataNameEqualityComparer <INamedTypeSymbol> .Instance); allItems[objectType] = new TypeHierarchyItem(objectType, isExternal: true); foreach (INamedTypeSymbol type in types) { INamedTypeSymbol t = type.BaseType; while (t != null) { if (!allItems.ContainsKey(t.OriginalDefinition)) { allItems[t.OriginalDefinition] = new TypeHierarchyItem(t.OriginalDefinition, isExternal: true); } t = t.BaseType; } } TypeHierarchyItem root = FillHierarchyItem(allItems[objectType], null); ImmutableArray <TypeHierarchyItem> interfaces = allItems .Select(f => f.Value) .OrderBy(f => f.Symbol, comparer) .ToImmutableArray(); return(new TypeHierarchy(root, interfaces)); TypeHierarchyItem FillHierarchyItem(TypeHierarchyItem item, TypeHierarchyItem parent) { INamedTypeSymbol symbol = item.Symbol; item.Parent = parent; allItems.Remove(symbol); TypeHierarchyItem[] derivedTypes = allItems .Select(f => f.Value) .Where(f => MetadataNameEqualityComparer <INamedTypeSymbol> .Instance.Equals(f.Symbol.BaseType?.OriginalDefinition, symbol.OriginalDefinition)) .ToArray(); if (derivedTypes.Length > 0) { if (symbol.SpecialType == SpecialType.System_Object) { Array.Sort(derivedTypes, (x, y) => { if (x.Symbol.IsStatic) { if (!y.Symbol.IsStatic) { return(-1); } } else if (y.Symbol.IsStatic) { return(1); } return(Compare(x, y)); }); } else { Array.Sort(derivedTypes, Compare); } FillHierarchyItems(derivedTypes, item, FillHierarchyItem); } return(item); } INamedTypeSymbol FindObjectType() { foreach (INamedTypeSymbol type in types) { INamedTypeSymbol t = type; do { if (t.SpecialType == SpecialType.System_Object) { return(t); } t = t.BaseType; } while (t != null); } return(null); } int Compare(TypeHierarchyItem x, TypeHierarchyItem y) { return(-comparer.Compare(x.Symbol, y.Symbol)); } }
private TypeHierarchy(TypeHierarchyItem root, ImmutableArray <TypeHierarchyItem> interfaces) { Root = root; Interfaces = interfaces; }