Analyze your C# Source files using PowerShell and the Get-RoslynInfo Cmdlet

by Doug Finke on October 30, 2011

I’ve been playing with the Roslyn CTP and PowerShell, including the C#Interactive window. I have worked up a start at a PowerShell cmdlet, Get-RoslynInfo, around the SyntaxWalker.

Get-RoslynInfo let’s me walk up to directory, get a listing of all C# files and then pipe it to my custom Roslyn SyntaxWalker, PipelinedSyntaxWalker, which visits the Classes and Methods and gives the results below. It shows me the name the declaration, either the class name or method name, the file it is in (including the full file name) and the line number it was found on.

The visitor I implemented only visits Classes and Methods, this can be easily extended (see the download).

ls . -Recurse *.cs | Get-RoslynInfo | Format-Table -AutoSize
# Results            
Name                   Kind                    LineNumber FileName               LiteralPath
----                   ----                    ---------- --------               -----------
PowerShellRoslynCmdlet ClassDeclarationSyntax           7 PowerShellRoslynCmdlet C:\PoSH\Roslyn\PowerShellAndRoslyn\...
ProcessRecord          MethodDeclarationSyntax         12 PowerShellRoslynCmdlet C:\PoSH\Roslyn\PowerShellAndRoslyn\...
TheTreeWalker          ClassDeclarationSyntax           5 TheTreeWalker          C:\PoSH\Roslyn\PowerShellAndRoslyn\...
VisitClassDeclaration  MethodDeclarationSyntax         20 TheTreeWalker          C:\PoSH\Roslyn\PowerShellAndRoslyn\...
VisitMethodDeclaration MethodDeclarationSyntax         26 TheTreeWalker          C:\PoSH\Roslyn\PowerShellAndRoslyn\...
GetDetails             MethodDeclarationSyntax         32 TheTreeWalker          C:\PoSH\Roslyn\PowerShellAndRoslyn\...

Let’s try it on the Nuget Source Code

It takes a little over a second, using the Measure-Command cmdlet,  to search the Nuget Source and find 781 C# files and report back more than 4,500 items. Piping this to the PowerShell Group cmdlet,  I can see there are 705 classes and 3,800+ methods defined.

image

Out-GridView

Now, I can type six characters and view all the class names and methods names. The Out-GridView (ships with PowerShell) comes equipped with a filter box too, letting me search all the columns for any text and subsetting the list.

$r | ogv # Out-GridView

image

Find Classes and Methods with the word Options in their Name

$r | ?{$_.name -match 'options'} | Format-Table

image

Find a Specific Name

Here I am using the simplified PowerShell Version 3 Where syntax and a RegEx.

$r | ? name -match '^extractoptions$'

image

I can pipe this to cat, aliased to Get-Content, and dump the file to the screen.

$r | ? name -match '^extractoptions$' | cat

image

Thoughts

I worked up this prototype to get a sense of the approach. It’s a quick way to slice and dice information about C# source files. I can see layering a ShowUI GUI (ShowUI is a PowerShell module to help build WPF user interfaces in script) on top of this to create a lightweight analysis tool that can pivot the data in many ways.

Plus, the amount of code to put this together is amazingly small and it plugs right into the PowerShell ecosystem. Leveraging scripting and system language to build a powerful set of tools.

Next up, visiting more C# elements and using the Sematic Model of Roslyn to do additional analysis.

Download the Code

Here’s the code and please leave feedback on what you like or would like to see.

 

You need to downloaded and install the Roslyn CTP to get these to work.

{ 2 trackbacks }

The Morning Brew - Chris Alcock » The Morning Brew #970
10.31.11 at 3:50 am
DotNetKicks.com
11.02.11 at 10:44 pm

{ 1 comment… read it below or add one }

Paulo Morgado 10.31.11 at 1:54 pm

I’m thinking of how fun a PSDrive for assemblies would be. Navigating namespaces as directories (like registry keys) and types as items.

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>