Powershell Ise's abstract syntax tree programming example _powershell

Source: Internet
Author: User
Tags function definition

One reason I really like Windows PowerShell Ise is that it exposes its underlying scripting object model to the user, allowing users to customize the scripting experience in their own way and need.
The core of the custom Ise is the $psise object. $psISE object allows users to control many aspects of ISE functionality. Here you can get an introduction to the Layered object model for $psise and the features associated with those objects.

This article will discuss how you can use the interpreter interface provided by PowerShell to combine the charm of the Ise object model to create a tool for scripting analysis and quick positioning.

Imagine that you have to analyze a relatively large PowerShell script. The script may have been written by someone else, and it may have been written by yourself a few months ago and thrown away for a long time. PowerShell Ise has done a great job, and it provides a scripting environment. You can expand its functionality by adding add-on (additional tools) to make your scripting experience better and more efficient. Starting with PowerShell 3.0, the abstract Syntax tree (AST) of the script can be easily obtained using the syntax interpreter interface. The following script Guild gets the AST of the script in the currently open ISE:

Copy Code code as follows:

$AbstractSyntaxTree = [System.Management.Automation.Language.Parser]::
Parseinput ($psISE. CurrentFile.Editor.Text, [ref] $null, [ref] $null)

Next, let's query all the functions in the script:

Copy Code code as follows:

$functionsInFile = $AbstractSyntaxTree. FindAll ({$args [0]-is
[System.Management.Automation.Language.FunctionDefinitionAst]}, $true)

Aside from the definition of function positioning, it would be pretty if we could get back to where we were before the cursor. This is also very easy to achieve. All we have to do is store the line numbers and reverse them in reverse order. (Does anyone already know, "stack")

The following script block shows the implementation of the go-to definition.

Copy Code code as follows:

#Define some useful global variables

$global: __isegotoaddoncurrline=1

$global: __isegotoaddoncurrcol=1

$global: __isegotoaddonlinetogoto=1

$global: __isegotoaddoncoltogoto=1

#We need two stacks-one each for line and column

$global: __isegotoaddonstackofline = New-object System.Collections.Stack

$global: __isegotoaddonstackofcol = New-object System.Collections.Stack

#This script block has the logic for the implementation of the GO-TO definition functionality

$global: __isegotoaddonscriptblockgoto =

{

$AbstractSyntaxTree =[system.management.automation.language.parser]::P arseinput ($psISE. CurrentFile.Editor.Text, [Ref] $null, [ref] $null)

$functionsInFile = $AbstractSyntaxTree. FindAll (

{$args [0]-is[system.management.automation.language.functiondefinitionast]}, $true)

#Get the text of the line where we have the cursor

$str = $psISE. CurrentFile.Editor.CaretLineText

#Store them on the stack of later use

$global: __isegotoaddonstackofline.push ($psISE. CurrentFile.Editor.CaretLine)

$global: __isegotoaddonstackofcol.push ($psISE. CurrentFile.Editor.CaretColumn)

$global: __isegotoaddoncurrline = $global: __isegotoaddonstackofline.peek ()

$global: __isegotoaddoncurrcol = $global: __isegotoaddonstackofcol.peek ()

#Get the selected text so this it can be used for searching existing functions

$selectedFunction = $psISE. CurrentFile.Editor.SelectedText

#Ensure that's cursor is somewhere between the word boundaries the function

$functionsInFile | %{if ($str. Contains ($_.name)) '

–and ($global: __isegotoaddoncurrcol-ge

$str. IndexOf ($_.name)) '

-and ($global: __isegotoaddoncurrcol-le

($str. IndexOf ($_.name) +$_.name.length))

)

{$selectedFunction = $_.name}

}

if ($selectedFunction-ne "")

{

#See if the selected function exists in the current open file

$functionToGoTo = $functionsInFile |? {$_.NAME-EQ "$selectedFunction"}

$global: __isegotoaddonlinetogoto = $functionToGoTo. Extent.startlinenumber

$global: __isegotoaddoncoltogoto = $functionToGoTo. Extent.startcolumnnumber

}

if ($functionToGoTo-eq $null)

{

Try

{

$comm = Get-command-name "$selectedFunction"-erroraction silentlycontinue

$comm. Definition | Out-gridview

}

catch [System.Exception]

{

}

}

Else

{

#Select the function definition, assuming the function name immediately follows the keyword ' function '

Try

{

$psise. CurrentFile.Editor.Select ($global: __isegotoaddonlinetogoto,

($global: __isegotoaddoncoltogoto+9),

$global: __isegotoaddonlinetogoto,

($global: __isegotoaddoncoltogoto+8+ $selectedFunction. length+1))

}

catch [System.Exception]

{

}

}

}

To add, the Go-to definition feature, if present in the current PowerShell session, shows the definition of the selected text. (in addition, the above script is just a simple example, if your "function" keyword and function name appear on the same line as the script.) This is not necessary in PowerShell, so if your scripting style is different, you may need to fine-tune the logic. )

You should then add these scripts to the add-on menu and use it as a command for the selected script. Here are two lines to do this.

Copy Code code as follows:

$global: __ISEGOTOADDONSB1 =
{& $global: __isegotoaddonscriptblockgoto | Out-null}
$null = $psISE. CURRENTPOWERSHELLTAB.ADDONSMENU.SUBMENUS.ADD (
"Go Do definition", $global: __isegotoaddonsb1, "F12")

Now let's see how we can implement the Go-back function, using our defined global stack, a few lines of code:

Copy Code code as follows:

$global: __isegotoaddonscriptblockgoback =

{

Try

{

#Pop the line and column numbers from the stack to do a reverse traversal

$global: __isegotoaddoncurrline =

$global: __isegotoaddonstackofline.pop ()

$global: __isegotoaddoncurrcol =

$global: __isegotoaddonstackofcol.pop ()

$psISE. CurrentFile.Editor.SetCaretPosition (

$global: __isegotoaddoncurrline, $global: __isegotoaddoncurrcol)

$psISE. CurrentFile.Editor.SelectCaretLine ();

}

catch [System.Exception]

{

}

}

$global: __ISEGOTOADDONSB2 = {& $global: __isegotoaddonscriptblockgoback | Out-null}

$null = $psISE. CURRENTPOWERSHELLTAB.ADDONSMENU.SUBMENUS.ADD ("Go Back", $global: __ISEGOTOADDONSB2, "Shift+f12")

Here it is, with only a few PowerShell code that implements the GO-TO definition (steering definition) and Go-back (return) features in Visual Studio.

You can also continue to expand the script to include these tasks: such as displaying all the functions in the script, clicking the function to go to the function definition. As an encouragement to further extend the functionality, let me show you what my ISE add-on tool looks like.

Extended PowerShell ISE in the Additional Tools menu

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.