void TrackMethodUsage(Type type) { foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) { var degenericMethod = DegenerifyMethod(method); _graph[type].Add(degenericMethod, false); UnusedMethods[type].Add(degenericMethod); if (method.IsVirtual) { var baseMethodCalled = DegenerifyMethod(method.GetBaseDefinition()); if (!_interfaceToImplementationMap.ContainsKey(baseMethodCalled.DeclaringType)) { _interfaceToImplementationMap.Add(baseMethodCalled.DeclaringType, new TypeFriendlyDictionary <MethodBase, List <MethodBase> >()); } if (!_interfaceToImplementationMap[baseMethodCalled.DeclaringType].ContainsKey(baseMethodCalled)) { _interfaceToImplementationMap[baseMethodCalled.DeclaringType].Add(baseMethodCalled, new List <MethodBase>()); } if (!_interfaceToImplementationMap[baseMethodCalled.DeclaringType][baseMethodCalled].Contains(degenericMethod)) { _interfaceToImplementationMap[baseMethodCalled.DeclaringType][baseMethodCalled].Add(degenericMethod); } } } }
internal bool HasMethodBeenSeen(MethodBase methodBase, Action <Type> callback) { var method = DegenerifyMethod(methodBase); var declaringType = DegenerifyType(methodBase.DeclaringType); if (!IsMethodWeShouldTrack(method)) { if (!_methodsWeShouldntTrack.ContainsKey(method)) { _methodsWeShouldntTrack.Add(method, true); return(false); } else { return(true); } } // have we already looked at this method before if (_graph[declaringType].ContainsKey(method)) { if (_graph[declaringType][method]) { return(true); } _graph[declaringType][method] = true; } UnusedMethods[declaringType].Remove(method); return(false); }
internal void GenerateMethodGraph(List <Assembly> assembliesToAnalyze) { assembliesToAnalyze.AddRange(_plugins.SelectMany(p => p.ListOtherFoundAssemblies())); _graph = new TypeFriendlyDictionary <Type, TypeFriendlyDictionary <MethodBase, bool> >(); foreach (var assembly in assembliesToAnalyze) { foreach (var type in assembly.GetTypes()) { if (type.FullName.Contains("<")) { continue; // skip anonymous types } var degenericedType = DegenerifyType(type); _graph.Add(degenericedType, new TypeFriendlyDictionary <MethodBase, bool>()); UnusedMethods.Add(type, new List <MethodBase>()); if (!degenericedType.IsInterface) { TrackInterfaceImplementations(degenericedType); } TrackMethodUsage(degenericedType); _unusedClasses.Add(degenericedType, false); } } }
internal void FinalizeReport() { UnusedClasses = _plugins .Select(p => (Func <IEnumerable <Type>, IEnumerable <Type> >)p.FilterUnusedTypes) .Aggregate(_unusedClasses.Keys.AsEnumerable(), (s, f) => f(s), f => f) .ToList(); var newUnusedMethods = new TypeFriendlyDictionary <Type, List <MethodBase> >(); var plugins = _plugins.Select(p => (Func <IEnumerable <MethodBase>, IEnumerable <MethodBase> >)p.FilterUnusedMethods).ToList(); foreach (var entry in UnusedMethods) { newUnusedMethods.Add(entry.Key, plugins .Aggregate(entry.Value.AsEnumerable(), (s, f) => f(s), f => f) .ToList()); } }