PowerShell ISE Addon: ISE Function Explorer using the PowerShell 3.0 parser

Last month, I wrote here about an ISE addon that used PowerShell psparser and Out-GridView cmdlet to show all the functions available in a script in PowerShell ISE. After that, Jason Shirk — a language developer — from the PowerShell team pointed to some PowerShell 3.0 beauty – the new language parser.

NOTE: The following code works only with PowerShell 3.0 RC and later.

Thanks to Jason, here is the new ISE function explorer code:

$scriptBlock = {
    $ast = [System.Management.Automation.Language.Parser]::ParseInput(
        $psISE.CurrentFile.Editor.Text, [ref]$null, [ref]$null)

    $functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst]}, $true) |
        ForEach-Object {
            [pscustomobject]@{
                Name = $_.Name
                Content = $_.Extent.Text
                StartLine = $_.Extent.StartLineNumber
                StartColumn = $_.Extent.StartColumnNumber
            }
        }

    $selectedLine = $functions | Out-GridView -PassThru
    if ($selectedLine)
    {
        $psISE.CurrentFile.Editor.SetCaretPosition($selectedLine.StartLine, $selectedLine.StartColumn)
    }
}

$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("ISE Function _Explorer", $scriptBlock, "Ctrl+Alt+E")

This is how the new function explorer looks.

Function Explorer

Function Explorer

Look at the number of lines in the above code and how easy it is to get a list of functions in my module. This is possible because of the improvements to the PowerShell parser in 3.0. The ParseInput() method takes the script contents as input and returns ScriptBlockAst as the output.

AST refers to Abstract Syntax Tree [http://en.wikipedia.org/wiki/Abstract_syntax_tree]

Once we have the output from the parser, we can use FindAll() method to search only for the function definitions by specifying FunctionDefinitionAst as the predicate.

The FunctionDefinitionAst represents both functions and filters. The second parameter on the FindAll() method decides if nested script blocks should be included or not. So, by setting this to $false, we can avoid listing the nested function definitions in the ISE function explorer.

$functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst]}, $false)

This is it. More on the capabilities of the parser later!

  • http://www.facebook.com/profile.php?id=715332530 Doug Finke

    Great post! The AST is a great addition to the PowerShell toolkit!