Only recently I found some tools that can help in this task (and the most promising one isn't yet available) and are affordable or even free (I don't know if many of the commercial tools are better).
The first tool, known by many programmers, but (in my opinion) used by few (me included) is FxCop by Microsoft. The tool is a code analysis tool, that does some style checking and validates that software conforms to a set of rules, signaling non conformities as defects. In my experience, if the tool is used from the start of a project, it may succeed. On a project already built, it's difficult to use (on a recent project that I work in, it found over 1000 errors. I didn't check if they were false positives or errors that can be dismissed as minor inconsistencies).
The next one, is nDepend . It allows the identification of problem areas in the overall architecture of a program (solution), identifying big/complex methods, non-cohesive classes and helps in understanding the program at an higher level. It allows the definition of rules and alerts with a SQL like language. The site has some videos showing its usage.
I haven't tried it yet on a complex project, but if it easily allows to flag calls from one layer to the wrong layer (UI to data, or business to UI) it seems promising. Another feature that I'm eager to try is the generation of metrics (# lines, # methods, # classes, cyclomatic complexity, % comments).
A little on the side are the "projects" like AspectC# and other languages that allow the separation of concerns and the "injection" of code, that could be used and parametrized to catch some of these errors. But it's a hard task just to get to a point that provides an interesting return on the investment made (in setup and parameterization time).
The last tool that I read about (this one isn't out yet), is nStatic. Now if this tool does half of what's shown and talked in Wesner Moise's blog, it will be a life saver. Apparently it interprets the program not as lines of code in a text file (like most IDEs do today), but in an functional way in internal memory (maybe those ASTs - syntax trees that we learned in compiler classes). With this representation, and using an AI workbench, it computes the paths in the program that generate errors (and the assumptions for those errors).
This reminds me of the first time I heard of an internal representation that wasn't the text source file . I think it was Visual Age for Java, that stored the tree representing the program in a DB . This approach (VA failed maybe for being ahead of it's time, and some shortcomings in speed and in error tolerance) has an enormous potential as shown by the current projects by JetBrains with Metaprogramming System and Intentional Software (I haven't tried either and I don't know if Intentional Software has some tool available for test). Just imagine the refactorings possible this way. And if it's possible to plug-in in to this representation, it would be much easier to find coupling mistakes (between layers), copy-pasted code, etc..
But back to nStatic, one of the features mentioned was finding the possible exceptions for a method and it's assumptions (for the exception). That will assist in finding many subtle errors. I'm just curious to try the tool (I'm thinking in applying for the beta), and have some questions/requests:
- will it allow to detect similar or duplicate code (I found Simian, but I haven't tried it on my complex project that I know has much similar code, to figure out if the match is by line or by abstract representation of the code)?
- will it be extensible, or allow access to the internal representation of the code, or provide an API?
- can the scan focus on one particular method (and be completely thorough with that method)?
- will it allow a fine grained control over loops (limit the # of times in a particular loop by annotation or coment) and other constructs?
- will it allow exporting graphs, assumptions to a XML/text format?
- it could be used to track dependencies(?) between assemblies/classes?
- could it generate some metrics, and integrate some features from other tools, meaning that it would be the only code analysis tool needed :)