Skip to content

Commit

Permalink
New PSSA custom rule for opening braces
Browse files Browse the repository at this point in the history
- Add Script Analyzer custom rule to test functions and statements so that
  opening braces are set according to the style guideline (issue PowerShell#27).
  • Loading branch information
johlju committed Jul 31, 2017
1 parent 104da5c commit 5f1459e
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 1 deletion.
214 changes: 213 additions & 1 deletion DscResource.AnalyzerRules/DscResource.AnalyzerRules.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,216 @@ function Measure-ParameterBlockParameterAttribute
}
}

Export-ModuleMember -Function Measure*
<#
.SYNOPSIS
Validates the function block braces and new lines around braces.
.DESCRIPTION
Each function should have the opening brace on a separate line. Also, the
opening brace should be followed by a new line.
.EXAMPLE
Measure-FunctionBlockBraces -ScriptBlockAst $ScriptBlockAst
.INPUTS
[System.Management.Automation.Language.ScriptBlockAst]
.OUTPUTS
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
.NOTES
None
#>
function Measure-FunctionBlockBraces
{
[CmdletBinding()]
[OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.ScriptBlockAst]
$ScriptBlockAst
)

Process
{
$results = @()

try
{
$diagnosticRecordType = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord'

$findAllFunctionsFilter = {
$args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst]
}

[System.Management.Automation.Language.Ast[]] $functionsAst = $ScriptBlockAst.FindAll( $findAllFunctionsFilter, $true )

foreach ($functionAst in $functionsAst)
{
$functionExtentRows = ($functionAst.Extent -split '\r\n')

# Check so that an opening brace does not exist on the same line as the function name.
if ($functionExtentRows[0] -match '\{')
{
$results += New-Object `
-Typename $diagnosticRecordType `
-ArgumentList @(
$localizedData.FunctionOpeningBraceNotOnSameLine, `
$functionAst.Extent, `
$PSCmdlet.MyInvocation.InvocationName, `
'Warning', `
$null
)
} # if

# Check so that an opening brace is followed by a new line.
if ($functionExtentRows[1] -match '\{.+')
{
$results += New-Object `
-Typename $diagnosticRecordType `
-ArgumentList @(
$localizedData.FunctionOpeningBraceShouldBeFollowedByNewLine, `
$functionAst.Extent, `
$PSCmdlet.MyInvocation.InvocationName, `
'Warning', `
$null
)
} # if

# Check so that an opening brace is followed by only one new line.
if ($functionExtentRows[2].Trim() -eq '')
{
$results += New-Object `
-Typename $diagnosticRecordType `
-ArgumentList @(
$localizedData.FunctionOpeningBraceShouldBeFollowedByOnlyOneNewLine, `
$functionAst.Extent, `
$PSCmdlet.MyInvocation.InvocationName, `
'Warning', `
$null
)
} # if
}

return $results
}
catch
{
$PSCmdlet.ThrowTerminatingError($PSItem)
}
}
}

<#
.SYNOPSIS
Validates the statement block braces and new lines around braces.
.DESCRIPTION
Each statement should have the opening brace on a separate line. Also, the
opening brace should be followed by a new line.
.EXAMPLE
Measure-StatementBlockBraces -ScriptBlockAst $ScriptBlockAst
.INPUTS
[System.Management.Automation.Language.ScriptBlockAst]
.OUTPUTS
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
.NOTES
None
#>
function Measure-StatementBlockBraces
{
[CmdletBinding()]
[OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.ScriptBlockAst]
$ScriptBlockAst
)

Process
{
$results = @()

try
{
$diagnosticRecordType = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord'

$findAllStatementBlockFilter = {
$args[0] -is [System.Management.Automation.Language.StatementBlockAst]
}

[System.Management.Automation.Language.Ast[]] $statementBlocksAst = $ScriptBlockAst.FindAll( $findAllStatementBlockFilter, $true )
$statementParentExtents = $statementBlocksAst.Parent.Extent

foreach ($statementParentExtent in $statementParentExtents)
{
$statementParentExtentRows = ($statementParentExtent.Text -split '\r\n')

# Check so that an opening brace does not exist on the same line as the statement.
if ($statementParentExtentRows[0] -match '\{')
{
$results += New-Object `
-Typename $diagnosticRecordType `
-ArgumentList @(
$localizedData.StatementOpeningBraceNotOnSameLine, `
$statementParentExtent, `
$PSCmdlet.MyInvocation.InvocationName, `
'Warning', `
$null
)
} # if
} # foreach parameter

$statementExtents = $statementBlocksAst.Extent

foreach ($statementExtent in $statementExtents)
{
$statementExtentRows = ($statementExtent.Text -split '\r\n')

# Check so that an opening brace is followed by a new line.
if ($statementExtentRows[0] -match '\{.+')
{
$results += New-Object `
-Typename $diagnosticRecordType `
-ArgumentList @(
$localizedData.StatementOpeningBraceShouldBeFollowedByNewLine, `
$statementExtent, `
$PSCmdlet.MyInvocation.InvocationName, `
'Warning', `
$null
)
} # if

# Check so that an opening brace is followed by only one new line.
if ($statementExtentRows[1].Trim() -eq '')
{
$results += New-Object `
-Typename $diagnosticRecordType `
-ArgumentList @(
$localizedData.StatementOpeningBraceShouldBeFollowedByOnlyOneNewLine, `
$statementExtent, `
$PSCmdlet.MyInvocation.InvocationName, `
'Warning', `
$null
)
} # if
} # foreach parameter

return $results
}
catch
{
$PSCmdlet.ThrowTerminatingError($PSItem)
}
}
}

Export-ModuleMember -Function Measure-*
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ ConvertFrom-StringData @'
ParameterBlockParameterAttributeMissing = A [Parameter()] attribute must be the first attribute of each parameter and be on its own line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#correct-format-for-parameter-block
ParameterBlockParameterAttributeLowerCase = The [Parameter()] attribute must start with an upper case 'P'. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#correct-format-for-parameter-block
ParameterBlockParameterAttributeWrongPlace = The [Parameter()] attribute must be the first attribute of each parameter. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#correct-format-for-parameter-block
FunctionOpeningBraceNotOnSameLine = Functions should not have the open brace on the same line as the function name. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-before-braces
FunctionOpeningBraceShouldBeFollowedByNewLine = Opening brace on function should be followed by a new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace
FunctionOpeningBraceShouldBeFollowedByOnlyOneNewLine = Opening brace on functions should only be followed by one new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace
StatementOpeningBraceNotOnSameLine = Statements should not have the open brace on the same line as the statement. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-before-braces
StatementOpeningBraceShouldBeFollowedByNewLine = Opening brace on statements should be followed by a new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace
StatementOpeningBraceShouldBeFollowedByOnlyOneNewLine = Opening brace on statements should only be followed by one new line. See https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md#one-newline-after-opening-brace
'@
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ Invoke-AppveyorAfterTestTask `
DscResource.Tests.
* Remove the $repoName variable and replace it with $moduleName as it was a
duplicate.
* Add Script Analyzer custom rule to test functions and statements so that
opening braces are set according to the style guideline ([issue #27](https://github.com/PowerShell/DscResource.Tests/issues/27)).

### 0.2.0.0

Expand Down

0 comments on commit 5f1459e

Please sign in to comment.