@@ -36,6 +36,12 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
36
36
37
37
foreach ( ScriptBlockAst scriptBlockAst in scriptBlockAsts )
38
38
{
39
+ // bail out if PS bound parameter used.
40
+ if ( scriptBlockAst . Find ( IsBoundParametersReference , searchNestedScriptBlocks : false ) != null )
41
+ {
42
+ continue ;
43
+ }
44
+
39
45
// find all declared parameters
40
46
IEnumerable < Ast > parameterAsts = scriptBlockAst . FindAll ( oneAst => oneAst is ParameterAst , false ) ;
41
47
@@ -45,12 +51,6 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
45
51
. GroupBy ( variableName => variableName , StringComparer . OrdinalIgnoreCase )
46
52
. ToDictionary ( variableName => variableName . Key , variableName => variableName . Count ( ) , StringComparer . OrdinalIgnoreCase ) ;
47
53
48
- // all bets are off if the script uses PSBoundParameters
49
- if ( variableCount . ContainsKey ( "PSBoundParameters" ) )
50
- {
51
- continue ;
52
- }
53
-
54
54
foreach ( ParameterAst parameterAst in parameterAsts )
55
55
{
56
56
// there should be at least two usages of the variable since the parameter declaration counts as one
@@ -72,6 +72,47 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
72
72
}
73
73
}
74
74
75
+ /// <summary>
76
+ /// Checks for PS bound parameter reference.
77
+ /// </summary>
78
+ /// <param name="ast">AST to be analyzed. This should be non-null</param>
79
+ /// <returns>Boolean true indicating that given AST has PS bound parameter reference, otherwise false</returns>
80
+ private static bool IsBoundParametersReference ( Ast ast )
81
+ {
82
+ // $PSBoundParameters
83
+ if ( ast is VariableExpressionAst variableAst
84
+ && variableAst . VariablePath . UserPath . Equals ( "PSBoundParameters" , StringComparison . OrdinalIgnoreCase ) )
85
+ {
86
+ return true ;
87
+ }
88
+
89
+ if ( ast is MemberExpressionAst memberAst
90
+ && memberAst . Member is StringConstantExpressionAst memberStringAst
91
+ && memberStringAst . Value . Equals ( "BoundParameters" , StringComparison . OrdinalIgnoreCase ) )
92
+ {
93
+ // $MyInvocation.BoundParameters
94
+ if ( memberAst . Expression is VariableExpressionAst veAst
95
+ && veAst . VariablePath . UserPath . Equals ( "MyInvocation" , StringComparison . OrdinalIgnoreCase ) )
96
+ {
97
+ return true ;
98
+ }
99
+
100
+ // $PSCmdlet.MyInvocation.BoundParameters
101
+ if ( memberAst . Expression is MemberExpressionAst meAstNested )
102
+ {
103
+ if ( meAstNested . Expression is VariableExpressionAst veAstNested
104
+ && veAstNested . VariablePath . UserPath . Equals ( "PSCmdlet" , StringComparison . OrdinalIgnoreCase )
105
+ && meAstNested . Member is StringConstantExpressionAst sceAstNested
106
+ && sceAstNested . Value . Equals ( "MyInvocation" , StringComparison . OrdinalIgnoreCase ) )
107
+ {
108
+ return true ;
109
+ }
110
+ }
111
+ }
112
+
113
+ return false ;
114
+ }
115
+
75
116
/// <summary>
76
117
/// GetName: Retrieves the name of this rule.
77
118
/// </summary>
0 commit comments