Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct casing of parameters as well in PSUseCorrectCasing formatter rule #1391

Merged
merged 4 commits into from
Jan 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions RuleDocumentation/UseCorrectCasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@

## Description

This is a style/formatting rule. PowerShell is case insensitive where applicable. The casing of cmdlet names does not matter but this rule ensures that the casing matches for consistency and also because most cmdlets start with an upper case and using that improves readability to the human eye.
This is a style/formatting rule. PowerShell is case insensitive where applicable. The casing of cmdlet names or parameters does not matter but this rule ensures that the casing matches for consistency and also because most cmdlets/parameters start with an upper case and using that improves readability to the human eye.

## How

Use exact casing of the cmdlet, e.g. `Invoke-Command`.
Use exact casing of the cmdlet and its parameters, e.g. `Invoke-Command { 'foo' } -RunAsAdministrator`.

## Example

### Wrong

``` PowerShell
invoke-command { 'foo' }
}
invoke-command { 'foo' } -runasadministrator
```

### Correct

``` PowerShell
Invoke-Command { 'foo' }
}
Invoke-Command { 'foo' } -RunAsAdministrator
```
6 changes: 3 additions & 3 deletions Rules/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Rules/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1081,13 +1081,13 @@
<value>Use space before pipe.</value>
</data>
<data name="UseCorrectCasingCommonName" xml:space="preserve">
<value>Use exact casing of cmdlet/function name.</value>
<value>Use exact casing of cmdlet/function/parameter name.</value>
</data>
<data name="UseCorrectCasingDescription" xml:space="preserve">
<value>For better readability and consistency, use the exact casing of the cmdlet/function.</value>
<value>For better readability and consistency, use the exact casing of the cmdlet/function/parameter.</value>
</data>
<data name="UseCorrectCasingError" xml:space="preserve">
<value>Cmdlet/Function does not match its exact casing '{0}'.</value>
<value>Cmdlet/Function/Parameter does not match its exact casing '{0}'.</value>
</data>
<data name="UseCorrectCasingName" xml:space="preserve">
<value>UseCorrectCasing</value>
Expand Down
48 changes: 46 additions & 2 deletions Rules/UseCorrectCasing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
using System.Management.Automation.Language;
using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic;
using System.Management.Automation;
using System.IO;
using System.Runtime.InteropServices;
using System.Linq;
#if !CORECLR
using System.ComponentModel.Composition;
#endif
Expand Down Expand Up @@ -67,6 +66,30 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
commandName,
suggestedCorrections: GetCorrectionExtent(commandAst, correctlyCasedCommandName));
}

var commandParameterAsts = commandAst.FindAll(
testAst => testAst is CommandParameterAst, true).Cast<CommandParameterAst>();
var availableParameters = commandInfo.Parameters;
foreach (var commandParameterAst in commandParameterAsts)
{
var parameterName = commandParameterAst.ParameterName;
var parameterMetaData = availableParameters[parameterName];
if (parameterMetaData != null)
{
var correctlyCasedParameterName = parameterMetaData.Name;
if (!parameterName.Equals(correctlyCasedParameterName, StringComparison.Ordinal))
{
yield return new DiagnosticRecord(
string.Format(CultureInfo.CurrentCulture, Strings.UseCorrectCasingError, commandName, parameterName),
GetCommandExtent(commandAst),
GetName(),
DiagnosticSeverity.Warning,
fileName,
commandName,
suggestedCorrections: GetCorrectionExtent(commandParameterAst, correctlyCasedParameterName));
}
}
}
}
}

Expand Down Expand Up @@ -109,6 +132,27 @@ private IEnumerable<CorrectionExtent> GetCorrectionExtent(CommandAst commandAst,
yield return correction;
}

private IEnumerable<CorrectionExtent> GetCorrectionExtent(CommandParameterAst commandParameterAst, string correctlyCaseName)
{
var description = string.Format(
CultureInfo.CurrentCulture,
Strings.UseCorrectCasingDescription,
correctlyCaseName,
correctlyCaseName);
var cmdExtent = commandParameterAst.Extent;
var correction = new CorrectionExtent(
cmdExtent.StartLineNumber,
cmdExtent.EndLineNumber,
// +1 because of the dash before the parameter name
cmdExtent.StartColumnNumber + 1,
// do not use EndColumnNumber property as it would not cover the case where the colon syntax: -ParameterName:$ParameterValue
cmdExtent.StartColumnNumber + 1 + commandParameterAst.ParameterName.Length,
correctlyCaseName,
commandParameterAst.Extent.File,
description);
yield return correction;
}

/// <summary>
/// GetName: Retrieves the name of this rule.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions Tests/Rules/UseCorrectCasing.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,15 @@ Describe "UseCorrectCasing" {
$scriptDefinition = ". $uncPath"
Invoke-Formatter $scriptDefinition | Should -Be $scriptDefinition
}

It "Corrects parameter casing" {
function Invoke-DummyFunction ($ParameterName) { }

Invoke-Formatter 'Invoke-DummyFunction -parametername $parameterValue' |
Should -Be 'Invoke-DummyFunction -ParameterName $parameterValue'
Invoke-Formatter 'Invoke-DummyFunction -parametername:$parameterValue' |
Should -Be 'Invoke-DummyFunction -ParameterName:$parameterValue'
Invoke-Formatter 'Invoke-DummyFunction -parametername: $parameterValue' |
Should -Be 'Invoke-DummyFunction -ParameterName: $parameterValue'
}
}