views:

222

answers:

7

I am looking for a way to programmatically inspect a .NET (C#, VB.NET,..) source code to perform static code analysis.

I'd like to perform queries on the code such as: - list classes whose name begin by x - list all the subclasses of x - list methods which instanciate an object of class x - determine if method x contains a variable named y - list methods calling the method y - ...

What I am looking for is an API or something else allowing me to write programs able to examine a source code.

+3  A: 

You can use System.Reflection, that should do the trick nicely for some of the things you want. As far as getting into the IL itself, check out Mono's Cecil.

MichaelGG
Unless, @monkeyget is looking at the source code. Then they'll probably want a parser.
kenny
Or a compiler :). Yea I uh missed that he said "source code". I guess NDepend and some of the IDE plugins might be of assistance then. Sorry!
MichaelGG
System.Reflection is indeed an option which i'll look into but it seems limited and i'm sure there must exist more powerful and simple tools for what I want to do.I mentioned source code in the question but a tool working on IL would be ok too.
Monkeyget
+1  A: 

Why not use FxCop for static code analysis?

Ruben Steins
Because he wants to WRITE software that will allow him to do what FxCop does.
Mike Hofer
+7  A: 

NDepend gives a SQL-like query language for querying .NET code structure.

stusmith
Brilliant tool. +1 for NDepend recommendation.
this. __curious_geek
Where's the programmatic interface in NDepend? In other words how can it be used from my own C# code?
Ash
I believe NDepend has some sort of programming/query language... however that's the limit of my knowledge. I guess you'd have to contact the NDepend people directly.
stusmith
+1  A: 

See the DMS Software Reengineering Toolkit.

DMS provides parsers that automatically build ASTs for many languages (C, C++, Java, C# [1.2, 2.0, 3.0 and 4.0], COBOL, ECMAScript, PHP, Verilog, ..) as well as symbol tables and control and data flow analysis for several of these.

DMS's pattern language can be used to match surface-syntax patterns, and combined with procedural analysis to ties code elements together with symbol table entries and various data flow relations. It has been used to implement a wide variety of program analysis tools, and is designed to be a foundation for you to build you own tool, without wasting a vast amount of time building basic program analysis infrastructure.

Ira Baxter
A: 

What about using the code model in Reflector? With the code model view add-in you should be able to get the idea of how to interrogate the structure of the code.

Hamish Smith
A: 

What about StyleCop? http://code.msdn.microsoft.com/sourceanalysis. But it doesn't support APIs.

Anuraj
A: 

To complete the stusmith's answer, NDepend comes with Code Query language (CQL). CQL is dedicated to write code quality rules that can be verified live in Visual Studio, or that can be verified during build process and reported in a HTML report. Here are a few samples of CQL rules (designed to be highly customizable):

Code refactored recently should be 100% covered by test:

WARN IF Count > 0 IN SELECT METHODS WHERE CodeWasChanged AND PercentageCoverage < 100

Complex methods should be commented:

WARN IF Count > 0 IN SELECT METHODS WHERE CyclomaticComplexity > 15 AND PercentageComment < 10

I don’t want that my User Interface layer to depend directly on the DataBase layer:

WARN IF Count > 0 IN SELECT NAMESPACES WHERE IsDirectlyUsing "DataLayer" AND NameIs "UILayer"

Static fields should not be named m_XXX (Custom naming conventions):

WARN IF Count > 0 IN SELECT FIELDS WHERE NameLike "^m_" AND IsStatic

Methods out of MyAssembly and MyAssembly2 should not have more than 30 lines of code:

WARN IF Count > 0 IN SELECT METHODS OUT OF ASSEMBLIES "MyAssembly1", "MyAssembly2" WHERE NbLinesOfCode > 30

Public methods should not be removed to avoid API breaking changes:

WARN IF Count > 0 IN SELECT METHODS WHERE IsPublic AND IsInOlderBuild AND WasRemoved

Types tagged with the attribute MyNamespace.FullCoveredAttribute must be thoroughly covered by tests:

WARN IF Count > 0 IN SELECT TYPES WHERE HasAttribute "MyNamespace.FullCoveredAttribute" AND PercentageCoverage < 100

Patrick Smacchia - NDepend dev