diff --git a/Rules/AvoidReservedParams.cs b/Rules/AvoidReservedParams.cs index b8aaa979c..d065fd881 100644 --- a/Rules/AvoidReservedParams.cs +++ b/Rules/AvoidReservedParams.cs @@ -30,43 +30,30 @@ public class AvoidReservedParams : IScriptRule public IEnumerable AnalyzeScript(Ast ast, string fileName) { if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); - IEnumerable paramAsts = ast.FindAll(testAst => testAst is ParameterAst, true); - Ast parentAst; + IEnumerable funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true); - string paramName; + List commonParamNames = typeof(CommonParameters).GetProperties().Select(param => param.Name).ToList(); - PropertyInfo[] commonParams = typeof(CommonParameters).GetProperties(); - List commonParamNames = new List(); - - if (commonParams != null) { - foreach (PropertyInfo commonParam in commonParams) { - commonParamNames.Add("$" + commonParam.Name); - } - } - - if (paramAsts != null) { - foreach (ParameterAst paramAst in paramAsts) { - paramName = paramAst.Name.ToString(); + foreach (FunctionDefinitionAst funcAst in funcAsts) + { + // this rule only applies to function with param block + if (funcAst.Body != null && funcAst.Body.ParamBlock != null + && funcAst.Body.ParamBlock.Attributes != null && funcAst.Body.ParamBlock.Parameters != null) + { + // no cmdlet binding + if (!funcAst.Body.ParamBlock.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(CmdletBindingAttribute))) + { + continue; + } - if (commonParamNames.Contains(paramName, StringComparer.OrdinalIgnoreCase)) { - parentAst = paramAst.Parent; - while (parentAst != null && !(parentAst is FunctionDefinitionAst)) { - parentAst = parentAst.Parent; - } + foreach (ParameterAst paramAst in funcAst.Body.ParamBlock.Parameters) + { + string paramName = paramAst.Name.VariablePath.UserPath; - if (parentAst is FunctionDefinitionAst) + if (commonParamNames.Contains(paramName, StringComparer.OrdinalIgnoreCase)) { - IEnumerable attrs = parentAst.FindAll(testAttr => testAttr is AttributeAst, true); - foreach (AttributeAst attr in attrs) - { - if (string.Equals(attr.Extent.Text, "[CmdletBinding()]", - StringComparison.OrdinalIgnoreCase)) - { - string funcName = string.Format(CultureInfo.CurrentCulture,Strings.ReservedParamsCmdletPrefix, (parentAst as FunctionDefinitionAst).Name); - yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ReservedParamsError, funcName,paramName), paramAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName); - - } - } + yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ReservedParamsError, funcAst.Name, paramName), + paramAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName); } } } diff --git a/Tests/Rules/AvoidReservedParams.tests.ps1 b/Tests/Rules/AvoidReservedParams.tests.ps1 index a2dbc475b..b6b70f42b 100644 --- a/Tests/Rules/AvoidReservedParams.tests.ps1 +++ b/Tests/Rules/AvoidReservedParams.tests.ps1 @@ -1,5 +1,5 @@ Import-Module ScriptAnalyzer -$violationMessage = [regex]::Escape('The cmdlet Verb-Files defines the reserved common parameter $Verbose.') +$violationMessage = [regex]::Escape("Verb-Files' defines the reserved common parameter 'Verbose'.") $violationName = "PSReservedParams" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName}