Skip to content

Commit

Permalink
Add foreach Assignment to AvoidAssignmentToAutomaticVariable (#2021)
Browse files Browse the repository at this point in the history
* Add Evaluation for foreach Assignment

* Add Tests for foreach Assignment

* Update Tests for Consistency

* Remove Unnecessary ExcludeRule

* Update Test Description

---------

Co-authored-by: PoshAJ <[email protected]>
  • Loading branch information
PoshAJ and PoshAJ authored Feb 25, 2025
1 parent d13809c commit 01a3259
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
25 changes: 25 additions & 0 deletions Rules/AvoidAssignmentToAutomaticVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
}
}

IEnumerable<Ast> forEachStatementAsts = ast.FindAll(testAst => testAst is ForEachStatementAst, searchNestedScriptBlocks: true);
foreach (ForEachStatementAst forEachStatementAst in forEachStatementAsts)
{
var variableExpressionAst = forEachStatementAst.Variable;
var variableName = variableExpressionAst.VariablePath.UserPath;
if (_readOnlyAutomaticVariables.Contains(variableName, StringComparer.OrdinalIgnoreCase))
{
yield return new DiagnosticRecord(DiagnosticRecordHelper.FormatError(Strings.AvoidAssignmentToReadOnlyAutomaticVariableError, variableName),
variableExpressionAst.Extent, GetName(), DiagnosticSeverity.Error, fileName, variableName);
}

if (_readOnlyAutomaticVariablesIntroducedInVersion6_0.Contains(variableName, StringComparer.OrdinalIgnoreCase))
{
var severity = IsPowerShellVersion6OrGreater() ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning;
yield return new DiagnosticRecord(DiagnosticRecordHelper.FormatError(Strings.AvoidAssignmentToReadOnlyAutomaticVariableIntroducedInPowerShell6_0Error, variableName),
variableExpressionAst.Extent, GetName(), severity, fileName, variableName);
}

if (_writableAutomaticVariables.Contains(variableName, StringComparer.OrdinalIgnoreCase))
{
yield return new DiagnosticRecord(DiagnosticRecordHelper.FormatError(Strings.AvoidAssignmentToWritableAutomaticVariableError, variableName),
variableExpressionAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, variableName);
}
}

IEnumerable<Ast> parameterAsts = ast.FindAll(testAst => testAst is ParameterAst, searchNestedScriptBlocks: true);
foreach (ParameterAst parameterAst in parameterAsts)
{
Expand Down
15 changes: 12 additions & 3 deletions Tests/Rules/AvoidAssignmentToAutomaticVariable.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,22 @@ Describe "AvoidAssignmentToAutomaticVariables" {
It "Variable <VariableName> produces warning of Severity <ExpectedSeverity>" -TestCases $testCases_AutomaticVariables {
param ($VariableName, $ExpectedSeverity)

$warnings = Invoke-ScriptAnalyzer -ScriptDefinition "`$${VariableName} = 'foo'" -ExcludeRule PSUseDeclaredVarsMoreThanAssignments
[System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "`$${VariableName} = 'foo'" -ExcludeRule PSUseDeclaredVarsMoreThanAssignments
$warnings.Count | Should -Be 1
$warnings.Severity | Should -Be $ExpectedSeverity
$warnings.RuleName | Should -Be $ruleName
}

It "Using Variable <VariableName> as parameter name produces warning of Severity error" -TestCases $testCases_AutomaticVariables {
It "Using Variable <VariableName> as foreach assignment produces warning of Severity <ExpectedSeverity>" -TestCases $testCases_AutomaticVariables {
param ($VariableName, $ExpectedSeverity)

[System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "foreach (`$$VariableName in `$foo) {}"
$warnings.Count | Should -Be 1
$warnings.Severity | Should -Be $ExpectedSeverity
$warnings.RuleName | Should -Be $ruleName
}

It "Using Variable <VariableName> as parameter name produces warning of Severity <ExpectedSeverity>" -TestCases $testCases_AutomaticVariables {
param ($VariableName, $ExpectedSeverity)

[System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "function foo{Param(`$$VariableName)}" -ExcludeRule PSReviewUnusedParameter
Expand All @@ -80,7 +89,7 @@ Describe "AvoidAssignmentToAutomaticVariables" {
$warnings.RuleName | Should -Be $ruleName
}

It "Using Variable <VariableName> as parameter name in param block produces warning of Severity error" -TestCases $testCases_AutomaticVariables {
It "Using Variable <VariableName> as parameter name in param block produces warning of Severity <ExpectedSeverity>" -TestCases $testCases_AutomaticVariables {
param ($VariableName, $ExpectedSeverity)

[System.Array] $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "function foo(`$$VariableName){}"
Expand Down

0 comments on commit 01a3259

Please sign in to comment.