/// <summary> /// Get base types for <paramref name="typeSymbol" /> /// </summary> /// <param name="typeSymbol">Type Symbol</param> /// <param name="hierarchyFilter">Type hierarchy filter</param> /// <returns>Base types</returns> internal static IEnumerable <ITypeSymbol> GetBaseTypes(this ITypeSymbol typeSymbol, TypeHierarchyFilter hierarchyFilter = TypeHierarchyFilter.All) { var typeName = typeSymbol.Name; if (_BaseTypeCache.ContainsKey(typeName)) { return(_BaseTypeCache[typeName]); } var typeSymbols = new HashSet <ITypeSymbol>(SymbolEqualityComparer.Default); typeSymbol.GatherBaseTypes(typeSymbols); _BaseTypeCache[typeName] = typeSymbols; var filterBehavior = FilterBehavior(hierarchyFilter, typeName); typeSymbols.RemoveWhere(symbol => filterBehavior(symbol)); return(typeSymbols); Func <ITypeSymbol, bool> FilterBehavior(TypeHierarchyFilter filter, string typeSymbolName) { Func <ITypeSymbol, bool> func; switch (filter) { case TypeHierarchyFilter.All: func = _ => false; break; case TypeHierarchyFilter.ExcludeItselt: func = symbol => symbol.Name.Equals(typeSymbolName, StringComparison.CurrentCulture); break; case TypeHierarchyFilter.OnlyItself: func = symbol => !symbol.Name.Equals(typeSymbolName, StringComparison.CurrentCulture); break; default: throw new ArgumentOutOfRangeException(nameof(hierarchyFilter), hierarchyFilter, null); } return(func); } }
/// <inheritdoc /> public IEnumerable <MemberEntry> GatherMethods(TypeHierarchyFilter filter, string indentation) { var baseTypes = _declaredTypeSymbol.GetBaseTypes(filter); var accessibleToOverride = GetOverridableSymbols(baseTypes); var overridableMethods = GetOverridableMethods(accessibleToOverride); var methods = new List <MemberEntry>(DefaultCapacity); methods.AddRange( from methodSymbol in overridableMethods let signature = methodSymbol.ToSignature() let summary = methodSymbol.GetSummary() let deferredCode = new Lazy <MemberDeclarationSyntax>(() => BuildOverridableMethod(methodSymbol, indentation)) select new MemberEntry { Signature = signature, Summary = summary, Code = deferredCode }); return(methods); }