Detecting unused code across multiple assemblies
In an older version of FX Cop (a few years ago now), I think there was a public class called Graph.
I wrote an app that used this class to detect unused code across multiple assemblies (we have 247 assemblies at present and around 4.5 million lines of code).
Is there any current way of performing the same operation with the current version of FX Cop?
We have an investigative set of re-factoring rules in development here, one check does what you describe. The check requires that you analyze a complete set of binaries which should, taken together, make use of all available public API. This might be a tall order for your case, since you have 247 binaries.
In any case, you can use the CallGraph static class to retrieve callers for a particular method:
MethodList callers = CallGraph.CallersFor(method);
If the length of the returned method list is > 0, there is at least one caller for the item. You'll likely also want to use a couple of other rule utility helpers to reduce noise. If the method is specially invoked (for example, if it's a public static Main entry point), you won't want to flag it. Neither will you want to flag overrides of virtual methods (since calls to overrides aren't typically emitted by compilers, a call site to the base definition is emitted instead).
RuleUtilities.IsSpeciallyInvoked(method)
RuleUtilities.IsOverride(method)
Michael Fanning
VSTS Development: Code Analysis
Hi,
does the call MethodList callers = CallGraph.CallersFor(method); return the callers from all assemblies listed as targets in the FxCop project, or is it restricted to the callers within the same assembly?Recently I implemented a dead code detector against the Reflector API and now want to add such a custom rule to FxCop.
One possible application of this rule are prototypes that want
to implement only a library subset required by a specific application.
thanks,
Roland
Yes, this method currently returns a complete list of callers to the requested method, across the current assembly set under analysis. We're actually revisiting this right now. The reason is that this approach requires us to hold state in memory relevant to the whole program set for all of analysis. This approach doesn't scale well.
A future version of FxCop will certainly provide all callers within the assembly. And it's possible we'll provide an alternate approach for cross-assembly information, with a pay-for-play implementation.
Michael
Yes, whole program analysis is expensive, this is why I asked. For me this is good, as I can do my task very easily now, at least with the current version.
Maybe you can provide something to merge the callgraphs for assemblies explicitly, which can be done during a breadth first traversal.
Thanks for the information.
greetings,
Roland
I managed to pull it off quite successfully - the simple answer is to dump any reflection information that is no longer required. Once the method / property is touched by any downstream assembly it no longer needs to exist.
This results in a fairly small overhead. Hopefully you don't have too many unused methods :)