In this about page, there is a code block (below) that shows off the $ForEach automatic variable, but it also has syntax like a subroutine in batch. I cannot find documentation on how this piece of code functions or what the language construct is called. I believe it's a PowerShell v5 addition, but reading the release notes didn't help me either. What does :tokenLoop foreach ($token in $tokens) represent?
function Get-FunctionPosition {
[CmdletBinding()]
[OutputType('FunctionPosition')]
param(
[Parameter(Position = 0, Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('PSPath')]
[System.String[]]
$Path
)
process {
try {
$filesToProcess = if ($_ -is [System.IO.FileSystemInfo]) {
$_
}
else {
Get-Item -Path $Path
}
foreach ($item in $filesToProcess) {
if ($item.PSIsContainer -or $item.Extension -notin @('.ps1', '.psm1')) {
continue
}
$tokens = $errors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile($item.FullName, ([REF]$tokens), ([REF]$errors))
if ($errors) {
Write-Warning "File '$($item.FullName)' has $($errors.Count) parser errors."
}
:tokenLoop foreach ($token in $tokens) {
if ($token.Kind -ne 'Function') {
continue
}
$position = $token.Extent.StartLineNumber
do {
if (-not $foreach.MoveNext()) {
break tokenLoop
}
$token = $foreach.Current
} until ($token.Kind -in @('Generic', 'Identifier'))
$functionPosition = [pscustomobject]@{
Name = $token.Text
LineNumber = $position
Path = $item.FullName
}
Add-Member -InputObject $functionPosition -TypeName FunctionPosition -PassThru
}
}
}
catch {
throw
}
}
}
In PowerShell
version 3.0 and up(at least since version 2.0), the following statement types are optionally labelled:switchforeachforwhiledoNow, what does this mean? It means that you can supply a label name as an argument to
breakorcontinuestatement inside the body of your labeled statement and have the flow control apply to the statement indicated by the label.Consider this example:
You might expect the "Let's process [...]" string to appear only twice, since we
continuein the case ofBob, but since the immediate parent statement is aswitch, it didn't actually apply to theforeachstatement.Now, if we can explicitly state that we want to continue the
foreachloop rather than the switch statement, we can avoid that:Now the
continuestatement actually continues the loop rather than the switch.Quite useful when you have nested loop constructs.
Labels are briefly discussed in conjunction with
breakinside awhilestatement in theabout_Breakhelp topic