using Microsoft.CodeAnalysis; using System; using System.Collections.Generic; using System.Linq; namespace ProxyInterfaceSourceGenerator.Utils { internal static class MemberHelper { private static string[] _excludedMethods = new string[] { "ToString", "GetHashCode" }; public static IEnumerable GetPublicProperties(INamedTypeSymbol classSymbol, params Func[] filters) { var allFilters = new List>(filters); allFilters.Add(p => p.Kind == SymbolKind.Property); return GetPublicMembers(classSymbol, allFilters.ToArray()); } public static IEnumerable GetPublicMethods(INamedTypeSymbol classSymbol, Func? filter = null) { if (filter is null) { filter = _ => true; } return GetPublicMembers(classSymbol, m => m.Kind == SymbolKind.Method, m => m.MethodKind == MethodKind.Ordinary, m => !_excludedMethods.Contains(m.Name), filter); } // TODO : do we need also to check for "SanitizedName()" here? private static IEnumerable GetPublicMembers(INamedTypeSymbol classSymbol, params Func[] filters) where T : ISymbol { var membersQuery = classSymbol.GetMembers().OfType() .Where(m => m.DeclaredAccessibility == Accessibility.Public); foreach (var filter in filters) { membersQuery = membersQuery.Where(filter); } var members = membersQuery.ToList(); var propertyNames = membersQuery.Select(x => x.Name); var baseType = classSymbol.BaseType; while (baseType != null) { var baseMembers = baseType.GetMembers().OfType() .Where(m => m.DeclaredAccessibility == Accessibility.Public) .Where(x => !propertyNames.Contains(x.Name)); foreach (var filter in filters) { baseMembers = baseMembers.Where(filter); } members.AddRange(baseMembers); baseType = baseType.BaseType; } return membersQuery; } } }