Skip to content

Commit b09c4e8

Browse files
liamjpetersandyleejordan
authored andcommitted
Check for ValueFromPipeline
1 parent d4fbdc3 commit b09c4e8

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

Rules/ReviewUnusedParameter.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using System.Management.Automation.Language;
88
using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic;
9+
using Microsoft.Windows.PowerShell.ScriptAnalyzer.Extensions;
910
#if !CORECLR
1011
using System.ComponentModel.Composition;
1112
#endif
@@ -102,6 +103,25 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
102103

103104
foreach (ParameterAst parameterAst in parameterAsts)
104105
{
106+
// Check if the parameter has the ValueFromPipeline attribute
107+
NamedAttributeArgumentAst valueFromPipeline = (NamedAttributeArgumentAst)parameterAst.Find(
108+
valFromPipelineAst => valFromPipelineAst is NamedAttributeArgumentAst namedAttrib && string.Equals(
109+
namedAttrib.ArgumentName, "ValueFromPipeline",
110+
StringComparison.OrdinalIgnoreCase
111+
),
112+
false
113+
);
114+
// If the parameter has the ValueFromPipeline attribute, check for usages of $_ or $PSItem
115+
if (valueFromPipeline?.GetValue() == true)
116+
{
117+
variableCount.TryGetValue("_", out int underscoreVariableCount);
118+
variableCount.TryGetValue("psitem", out int psitemVariableCount);
119+
if (underscoreVariableCount > 0 || psitemVariableCount > 0)
120+
{
121+
continue;
122+
}
123+
}
124+
105125
// there should be at least two usages of the variable since the parameter declaration counts as one
106126
variableCount.TryGetValue(parameterAst.Name.VariablePath.UserPath, out int variableUsageCount);
107127
if (variableUsageCount >= 2)

Tests/Rules/ReviewUnusedParameter.tests.ps1

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ Describe "ReviewUnusedParameter" {
2020
$Violations.Count | Should -Be 2
2121
}
2222

23+
It "has 1 violation - function with 1 parameter with ValueFromPipeline set to false and `$_ usage" {
24+
$ScriptDefinition = 'function BadFunc1 { param ([Parameter(ValueFromPipeline = $false)] $Param1) $_}'
25+
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName
26+
$Violations.Count | Should -Be 1
27+
}
28+
29+
It "has 1 violation - function with 1 parameter with ValueFromPipeline set to false and `$PSItem usage" {
30+
$ScriptDefinition = 'function BadFunc1 { param ([Parameter(ValueFromPipeline = $false)] $Param1) $PSItem}'
31+
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName
32+
$Violations.Count | Should -Be 1
33+
}
34+
2335
It "has 1 violation - scriptblock with 1 unused parameter" {
2436
$ScriptDefinition = '{ param ($Param1) }'
2537
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName
@@ -59,6 +71,30 @@ Describe "ReviewUnusedParameter" {
5971
$Violations.Count | Should -Be 0
6072
}
6173

74+
It "has no violation - function with 1 parameter with ValueFromPipeline explictly set to true and `$_ usage" {
75+
$ScriptDefinition = 'function BadFunc1 { param ([Parameter(ValueFromPipeline = $true)] $Param1) $_}'
76+
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName
77+
$Violations.Count | Should -Be 0
78+
}
79+
80+
It "has no violation - function with 1 parameter with ValueFromPipeline explictly set to true and `$PSItem usage" {
81+
$ScriptDefinition = 'function BadFunc1 { param ([Parameter(ValueFromPipeline = $true)] $Param1) $PSItem}'
82+
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName
83+
$Violations.Count | Should -Be 0
84+
}
85+
86+
It "has no violation - function with 1 parameter with ValueFromPipeline implicitly set to true and `$_ usage" {
87+
$ScriptDefinition = 'function BadFunc1 { param ([Parameter(ValueFromPipeline)] $Param1) $_}'
88+
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName
89+
$Violations.Count | Should -Be 0
90+
}
91+
92+
It "has no violation - function with 1 parameter with ValueFromPipeline implicitly set to true and `$PSItem usage" {
93+
$ScriptDefinition = 'function BadFunc1 { param ([Parameter(ValueFromPipeline)] $Param1) $PSItem}'
94+
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName
95+
$Violations.Count | Should -Be 0
96+
}
97+
6298
It "has no violations when using PSBoundParameters" {
6399
$ScriptDefinition = 'function Bound { param ($Param1) Get-Foo @PSBoundParameters }'
64100
$Violations = Invoke-ScriptAnalyzer -ScriptDefinition $ScriptDefinition -IncludeRule $RuleName

0 commit comments

Comments
 (0)