Exemple #1
0
        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;
            }
        }
Exemple #5
0
        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;
        }
Exemple #6
0
        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));
            }
        }
Exemple #7
0
 private TypeHierarchy(TypeHierarchyItem root, ImmutableArray <TypeHierarchyItem> interfaces)
 {
     Root       = root;
     Interfaces = interfaces;
 }