From 7f04508f3af7beb951794be3685e00697b5f671e Mon Sep 17 00:00:00 2001 From: kalgiz Date: Fri, 6 Apr 2018 10:56:39 -0700 Subject: [PATCH 01/11] Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. --- Engine/Helper.cs | 58 ++++++++---------------------- Rules/AvoidPositionalParameters.cs | 17 +++++++-- Rules/UseCmdletCorrectly.cs | 2 +- 3 files changed, 30 insertions(+), 47 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 4adf407ad..91c61b9f8 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -602,43 +602,33 @@ public bool HasSplattedVariable(CommandAst cmdAst) } /// - /// Given a commandast, checks whether positional parameters are used or not. + /// Given a commandast, checks if the command is a Cmdlet. /// /// - /// only return true if more than three positional parameters are used /// - public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositional = false) - { + public bool IsCmdlet(CommandAst cmdAst) { if (cmdAst == null) { return false; } - var commandInfo = GetCommandInfoLegacy(cmdAst.GetCommandName()); - if (commandInfo == null || (commandInfo.CommandType != System.Management.Automation.CommandTypes.Cmdlet)) - { - return false; - } - - IEnumerable switchParams = null; + var commandInfo = GetCommandInfo(cmdAst.GetCommandName()); + return (commandInfo != null && commandInfo.CommandType == System.Management.Automation.CommandTypes.Cmdlet); + } + /// + /// Given a commandast, checks whether positional parameters are used or not. + /// + /// + /// only return true if more than three positional parameters are used + /// + public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositional = false) + { if (HasSplattedVariable(cmdAst)) { return false; } - if (commandInfo != null && commandInfo.CommandType == System.Management.Automation.CommandTypes.Cmdlet) - { - try - { - switchParams = commandInfo.Parameters.Values.Where(pm => pm.SwitchParameter); - } - catch (Exception) - { - switchParams = null; - } - } - int parameters = 0; // Because of the way we count, we will also count the cmdlet as an argument so we have to -1 int arguments = -1; @@ -646,27 +636,7 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio foreach (CommandElementAst ceAst in cmdAst.CommandElements) { var cmdParamAst = ceAst as CommandParameterAst; - if (cmdParamAst != null) - { - // Skip if it's a switch parameter - if (switchParams != null && - switchParams.Any( - pm => String.Equals( - pm.Name, - cmdParamAst.ParameterName, StringComparison.OrdinalIgnoreCase))) - { - continue; - } - - parameters += 1; - - if (cmdParamAst.Argument != null) - { - arguments += 1; - } - - } - else + if (cmdParamAst == null) { arguments += 1; } diff --git a/Rules/AvoidPositionalParameters.cs b/Rules/AvoidPositionalParameters.cs index de530ab78..0d4bf27da 100644 --- a/Rules/AvoidPositionalParameters.cs +++ b/Rules/AvoidPositionalParameters.cs @@ -27,6 +27,18 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); + // Find all function definitions in the script and add them to the set. + IEnumerable functionDefinitionAsts = ast.FindAll(testAst => testAst is FunctionDefinitionAst, true); + HashSet declaredFunctionNames = new HashSet(); + + foreach (Ast foundAst in functionDefinitionAsts) { + FunctionDefinitionAst functionDefinitionAst = (FunctionDefinitionAst)foundAst; + if (string.IsNullOrEmpty(functionDefinitionAst.Name)) { + continue; + } + declaredFunctionNames.Add(functionDefinitionAst.Name); + } + // Finds all CommandAsts. IEnumerable foundAsts = ast.FindAll(testAst => testAst is CommandAst, true); @@ -39,9 +51,10 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) // MSDN: CommandAst.GetCommandName Method if (cmdAst.GetCommandName() == null) continue; - if (Helper.Instance.GetCommandInfoLegacy(cmdAst.GetCommandName()) != null - && Helper.Instance.PositionalParameterUsed(cmdAst, true)) + if ((Helper.Instance.IsCmdlet(cmdAst) || declaredFunctionNames.Contains(cmdAst.GetCommandName())) && + (Helper.Instance.PositionalParameterUsed(cmdAst))) { + Console.WriteLine("Cmdlet or function call"); PipelineAst parent = cmdAst.Parent as PipelineAst; if (parent != null && parent.PipelineElements.Count > 1) diff --git a/Rules/UseCmdletCorrectly.cs b/Rules/UseCmdletCorrectly.cs index fae21cfad..09d9ac1ea 100644 --- a/Rules/UseCmdletCorrectly.cs +++ b/Rules/UseCmdletCorrectly.cs @@ -129,7 +129,7 @@ private bool MandatoryParameterExists(CommandAst cmdAst) return true; } - if (mandParams.Count() == 0 || Helper.Instance.PositionalParameterUsed(cmdAst)) + if (mandParams.Count() == 0 || (Helper.Instance.IsCmdlet(cmdAst) && Helper.Instance.PositionalParameterUsed(cmdAst))) { returnValue = true; } From b3c577e2b6c945a498a86b91d4a1ff186994c27a Mon Sep 17 00:00:00 2001 From: kalgiz Date: Fri, 6 Apr 2018 13:37:05 -0700 Subject: [PATCH 02/11] Get rid of debug print. --- Rules/AvoidPositionalParameters.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Rules/AvoidPositionalParameters.cs b/Rules/AvoidPositionalParameters.cs index 0d4bf27da..e5e3469b5 100644 --- a/Rules/AvoidPositionalParameters.cs +++ b/Rules/AvoidPositionalParameters.cs @@ -54,7 +54,6 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) if ((Helper.Instance.IsCmdlet(cmdAst) || declaredFunctionNames.Contains(cmdAst.GetCommandName())) && (Helper.Instance.PositionalParameterUsed(cmdAst))) { - Console.WriteLine("Cmdlet or function call"); PipelineAst parent = cmdAst.Parent as PipelineAst; if (parent != null && parent.PipelineElements.Count > 1) From 365b5166d148518c845048686eb6d23f80f4accb Mon Sep 17 00:00:00 2001 From: kalgiz Date: Fri, 6 Apr 2018 13:47:58 -0700 Subject: [PATCH 03/11] Tests fpr PSAvoidPOsitionalParameters rule. --- Tests/Rules/AvoidPositionalParameters.tests.ps1 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Tests/Rules/AvoidPositionalParameters.tests.ps1 b/Tests/Rules/AvoidPositionalParameters.tests.ps1 index 8e95ca008..c4c8aab1d 100644 --- a/Tests/Rules/AvoidPositionalParameters.tests.ps1 +++ b/Tests/Rules/AvoidPositionalParameters.tests.ps1 @@ -26,4 +26,21 @@ Describe "AvoidPositionalParameters" { $noViolationsDSC.Count | Should -Be 0 } } + + Context "Function defined and called in script, which has 3 or more positional parameters triggers rule." { + $sb= + { + Function Foo { + param( + [Parameter(Mandatory=$true,Position=1)] $A, + [Parameter(Position=2)]$B, + [Parameter(Position=3)]$C) + } + Foo "a" "b" "c" + } + $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "$sb" + $warnings.Count | Should -BeGreaterThan 0 + $warning.RuleName | Should -Contain "PSAvoidUsingPositionalParameters" + $warnings.Message | Should -Contain "Cmdlet 'Foo' has positional parameter. Please use named parameters instead of positional parameters when calling a command." + } } From 5f0f90dbf79bd2857ff0edea3bcfde956e8ad7b2 Mon Sep 17 00:00:00 2001 From: kalgiz Date: Mon, 9 Apr 2018 16:40:36 -0700 Subject: [PATCH 04/11] Tests for AvoidPositionalParameters rule fixes. --- .../Rules/AvoidPositionalParameters.tests.ps1 | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Tests/Rules/AvoidPositionalParameters.tests.ps1 b/Tests/Rules/AvoidPositionalParameters.tests.ps1 index c4c8aab1d..2129de06d 100644 --- a/Tests/Rules/AvoidPositionalParameters.tests.ps1 +++ b/Tests/Rules/AvoidPositionalParameters.tests.ps1 @@ -21,26 +21,28 @@ Describe "AvoidPositionalParameters" { It "returns no violations" { $noViolations.Count | Should -Be 0 } - + It "returns no violations for DSC configuration" { $noViolationsDSC.Count | Should -Be 0 } } Context "Function defined and called in script, which has 3 or more positional parameters triggers rule." { - $sb= - { - Function Foo { - param( - [Parameter(Mandatory=$true,Position=1)] $A, - [Parameter(Position=2)]$B, - [Parameter(Position=3)]$C) + It "returns avoid positional parameters violation" { + $sb= + { + Function Foo { + param( + [Parameter(Mandatory=$true,Position=1)] $A, + [Parameter(Position=2)]$B, + [Parameter(Position=3)]$C) + } + Foo "a" "b" "c" } - Foo "a" "b" "c" + $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "$sb" + $warnings.Count | Should -BeGreaterThan 0 + $warnings.RuleName | Should -Contain "PSAvoidUsingPositionalParameters" + $warnings.Message | Should -Contain "Cmdlet 'Foo' has positional parameter. Please use named parameters instead of positional parameters when calling a command." } - $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "$sb" - $warnings.Count | Should -BeGreaterThan 0 - $warning.RuleName | Should -Contain "PSAvoidUsingPositionalParameters" - $warnings.Message | Should -Contain "Cmdlet 'Foo' has positional parameter. Please use named parameters instead of positional parameters when calling a command." } } From 1a2f9fe89ecb1edc1c4162b5cd80d00bc4044852 Mon Sep 17 00:00:00 2001 From: kalgiz Date: Tue, 10 Apr 2018 17:06:31 -0700 Subject: [PATCH 05/11] Counting positional parameters fix. --- Engine/Helper.cs | 23 +++++++++++------------ Rules/AvoidPositionalParameters.cs | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 91c61b9f8..ed4bb8ab5 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -629,16 +629,21 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio return false; } - int parameters = 0; // Because of the way we count, we will also count the cmdlet as an argument so we have to -1 - int arguments = -1; + int argumentsWithoutParameters = -1; + bool wasParameter = false; foreach (CommandElementAst ceAst in cmdAst.CommandElements) { var cmdParamAst = ceAst as CommandParameterAst; - if (cmdParamAst == null) + if (cmdParamAst != null) { - arguments += 1; + wasParameter = true; + } else { + if (!wasParameter) { + argumentsWithoutParameters += 1; + } + wasParameter = false; } } @@ -647,16 +652,10 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio if (parent != null && parent.PipelineElements.Count > 1 && parent.PipelineElements[0] != cmdAst) { - arguments += 1; - } - - // if we are only checking for 3 or more positional parameters, check that arguments < parameters + 3 - if (moreThanThreePositional && (arguments - parameters) < 3) - { - return false; + argumentsWithoutParameters += 1; } - return arguments > parameters; + return moreThanThreePositional ? argumentsWithoutParameters >= 3 : argumentsWithoutParameters > 0; } diff --git a/Rules/AvoidPositionalParameters.cs b/Rules/AvoidPositionalParameters.cs index e5e3469b5..abcf5c821 100644 --- a/Rules/AvoidPositionalParameters.cs +++ b/Rules/AvoidPositionalParameters.cs @@ -52,7 +52,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) if (cmdAst.GetCommandName() == null) continue; if ((Helper.Instance.IsCmdlet(cmdAst) || declaredFunctionNames.Contains(cmdAst.GetCommandName())) && - (Helper.Instance.PositionalParameterUsed(cmdAst))) + (Helper.Instance.PositionalParameterUsed(cmdAst, true))) { PipelineAst parent = cmdAst.Parent as PipelineAst; From 29f5017120de0ccf4c9737ca8a89d50ee66b63a1 Mon Sep 17 00:00:00 2001 From: kalgiz Date: Wed, 11 Apr 2018 16:43:41 -0700 Subject: [PATCH 06/11] Code cleanup for AvoidPositionalParameter rule fix. --- Engine/Helper.cs | 24 ++++++++++--------- Rules/AvoidPositionalParameters.cs | 7 +++--- Rules/UseCmdletCorrectly.cs | 2 +- .../Rules/AvoidPositionalParameters.tests.ps1 | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index ed4bb8ab5..efec80b92 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -620,9 +620,9 @@ public bool IsCmdlet(CommandAst cmdAst) { /// Given a commandast, checks whether positional parameters are used or not. /// /// - /// only return true if more than three positional parameters are used + /// only return true if more than three positional parameters are used /// - public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositional = false) + public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositional = false) { if (HasSplattedVariable(cmdAst)) { @@ -630,20 +630,22 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio } // Because of the way we count, we will also count the cmdlet as an argument so we have to -1 - int argumentsWithoutParameters = -1; - bool wasParameter = false; + int argumentsWithoutProcedingParameters = -1; + bool parameterPreceding = false; foreach (CommandElementAst ceAst in cmdAst.CommandElements) { var cmdParamAst = ceAst as CommandParameterAst; if (cmdParamAst != null) { - wasParameter = true; - } else { - if (!wasParameter) { - argumentsWithoutParameters += 1; + parameterPreceding = true; + } else + { + if (!parameterPreceding) + { + argumentsWithoutProcedingParameters += 1; } - wasParameter = false; + parameterPreceding = false; } } @@ -652,10 +654,10 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanThreePositio if (parent != null && parent.PipelineElements.Count > 1 && parent.PipelineElements[0] != cmdAst) { - argumentsWithoutParameters += 1; + argumentsWithoutProcedingParameters += 1; } - return moreThanThreePositional ? argumentsWithoutParameters >= 3 : argumentsWithoutParameters > 0; + return moreThanTwoPositional ? argumentsWithoutProcedingParameters >= 3 : argumentsWithoutProcedingParameters > 0; } diff --git a/Rules/AvoidPositionalParameters.cs b/Rules/AvoidPositionalParameters.cs index abcf5c821..0fa54845d 100644 --- a/Rules/AvoidPositionalParameters.cs +++ b/Rules/AvoidPositionalParameters.cs @@ -31,9 +31,10 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) IEnumerable functionDefinitionAsts = ast.FindAll(testAst => testAst is FunctionDefinitionAst, true); HashSet declaredFunctionNames = new HashSet(); - foreach (Ast foundAst in functionDefinitionAsts) { - FunctionDefinitionAst functionDefinitionAst = (FunctionDefinitionAst)foundAst; - if (string.IsNullOrEmpty(functionDefinitionAst.Name)) { + foreach (FunctionDefinitionAst functionDefinitionAst in functionDefinitionAsts) + { + if (string.IsNullOrEmpty(functionDefinitionAst.Name)) + { continue; } declaredFunctionNames.Add(functionDefinitionAst.Name); diff --git a/Rules/UseCmdletCorrectly.cs b/Rules/UseCmdletCorrectly.cs index 09d9ac1ea..8138e6dec 100644 --- a/Rules/UseCmdletCorrectly.cs +++ b/Rules/UseCmdletCorrectly.cs @@ -129,7 +129,7 @@ private bool MandatoryParameterExists(CommandAst cmdAst) return true; } - if (mandParams.Count() == 0 || (Helper.Instance.IsCmdlet(cmdAst) && Helper.Instance.PositionalParameterUsed(cmdAst))) + if (mandParams.Count == 0 || (Helper.Instance.IsCmdlet(cmdAst) && Helper.Instance.PositionalParameterUsed(cmdAst))) { returnValue = true; } diff --git a/Tests/Rules/AvoidPositionalParameters.tests.ps1 b/Tests/Rules/AvoidPositionalParameters.tests.ps1 index 2129de06d..95ddd6ef1 100644 --- a/Tests/Rules/AvoidPositionalParameters.tests.ps1 +++ b/Tests/Rules/AvoidPositionalParameters.tests.ps1 @@ -41,7 +41,7 @@ Describe "AvoidPositionalParameters" { } $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "$sb" $warnings.Count | Should -BeGreaterThan 0 - $warnings.RuleName | Should -Contain "PSAvoidUsingPositionalParameters" + $warnings.RuleName | Should -Contain $violationName $warnings.Message | Should -Contain "Cmdlet 'Foo' has positional parameter. Please use named parameters instead of positional parameters when calling a command." } } From 956fcde72d66f6207e52624c9e0c50ac23f44813 Mon Sep 17 00:00:00 2001 From: kalgiz Date: Fri, 6 Apr 2018 10:56:39 -0700 Subject: [PATCH 07/11] Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. --- Engine/Helper.cs | 12 +++++++++++- Rules/UseCmdletCorrectly.cs | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index efec80b92..a460d9cf8 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -620,7 +620,7 @@ public bool IsCmdlet(CommandAst cmdAst) { /// Given a commandast, checks whether positional parameters are used or not. /// /// - /// only return true if more than three positional parameters are used + /// only return true if more than two positional parameters are used /// public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositional = false) { @@ -629,6 +629,10 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona return false; } +<<<<<<< 29f5017120de0ccf4c9737ca8a89d50ee66b63a1 +======= + int parameters = 0; +>>>>>>> Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. // Because of the way we count, we will also count the cmdlet as an argument so we have to -1 int argumentsWithoutProcedingParameters = -1; bool parameterPreceding = false; @@ -636,6 +640,7 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona foreach (CommandElementAst ceAst in cmdAst.CommandElements) { var cmdParamAst = ceAst as CommandParameterAst; +<<<<<<< 29f5017120de0ccf4c9737ca8a89d50ee66b63a1 if (cmdParamAst != null) { parameterPreceding = true; @@ -646,6 +651,11 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona argumentsWithoutProcedingParameters += 1; } parameterPreceding = false; +======= + if (cmdParamAst == null) + { + arguments += 1; +>>>>>>> Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. } } diff --git a/Rules/UseCmdletCorrectly.cs b/Rules/UseCmdletCorrectly.cs index 8138e6dec..4016d12c3 100644 --- a/Rules/UseCmdletCorrectly.cs +++ b/Rules/UseCmdletCorrectly.cs @@ -129,7 +129,11 @@ private bool MandatoryParameterExists(CommandAst cmdAst) return true; } +<<<<<<< 29f5017120de0ccf4c9737ca8a89d50ee66b63a1 if (mandParams.Count == 0 || (Helper.Instance.IsCmdlet(cmdAst) && Helper.Instance.PositionalParameterUsed(cmdAst))) +======= + if (mandParams.Count() == 0 || (Helper.Instance.IsCmdlet(cmdAst) && Helper.Instance.PositionalParameterUsed(cmdAst))) +>>>>>>> Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. { returnValue = true; } From 014dd71ed6cc4a87605ba46b06383aa18ceb8792 Mon Sep 17 00:00:00 2001 From: kalgiz Date: Fri, 6 Apr 2018 13:47:58 -0700 Subject: [PATCH 08/11] Tests fpr PSAvoidPOsitionalParameters rule. --- Engine/Helper.cs | 10 ---------- Rules/UseCmdletCorrectly.cs | 4 ---- 2 files changed, 14 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index a460d9cf8..955c81abb 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -629,10 +629,6 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona return false; } -<<<<<<< 29f5017120de0ccf4c9737ca8a89d50ee66b63a1 -======= - int parameters = 0; ->>>>>>> Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. // Because of the way we count, we will also count the cmdlet as an argument so we have to -1 int argumentsWithoutProcedingParameters = -1; bool parameterPreceding = false; @@ -640,7 +636,6 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona foreach (CommandElementAst ceAst in cmdAst.CommandElements) { var cmdParamAst = ceAst as CommandParameterAst; -<<<<<<< 29f5017120de0ccf4c9737ca8a89d50ee66b63a1 if (cmdParamAst != null) { parameterPreceding = true; @@ -651,11 +646,6 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona argumentsWithoutProcedingParameters += 1; } parameterPreceding = false; -======= - if (cmdParamAst == null) - { - arguments += 1; ->>>>>>> Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. } } diff --git a/Rules/UseCmdletCorrectly.cs b/Rules/UseCmdletCorrectly.cs index 4016d12c3..8138e6dec 100644 --- a/Rules/UseCmdletCorrectly.cs +++ b/Rules/UseCmdletCorrectly.cs @@ -129,11 +129,7 @@ private bool MandatoryParameterExists(CommandAst cmdAst) return true; } -<<<<<<< 29f5017120de0ccf4c9737ca8a89d50ee66b63a1 if (mandParams.Count == 0 || (Helper.Instance.IsCmdlet(cmdAst) && Helper.Instance.PositionalParameterUsed(cmdAst))) -======= - if (mandParams.Count() == 0 || (Helper.Instance.IsCmdlet(cmdAst) && Helper.Instance.PositionalParameterUsed(cmdAst))) ->>>>>>> Trigger AvoidPositionalParameters rule for function defined and called inside a sript given as argument to Script Analyzer. { returnValue = true; } From 147b16f3b7396c79a4e62562421689f64c965854 Mon Sep 17 00:00:00 2001 From: kalgiz Date: Tue, 10 Apr 2018 17:06:31 -0700 Subject: [PATCH 09/11] Counting positional parameters fix. --- Engine/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 955c81abb..7d425fd93 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -657,7 +657,7 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona argumentsWithoutProcedingParameters += 1; } - return moreThanTwoPositional ? argumentsWithoutProcedingParameters >= 3 : argumentsWithoutProcedingParameters > 0; + return moreThanTwoPositional ? argumentsWithoutProcedingParameters > 2 : argumentsWithoutProcedingParameters > 0; } From b60f00dc86b75fab975c1c421b78bccadd97219f Mon Sep 17 00:00:00 2001 From: kalgiz Date: Thu, 12 Apr 2018 16:14:45 -0700 Subject: [PATCH 10/11] Tests fixes for AvoidPositionalParameters rule. --- Tests/Rules/AvoidPositionalParameters.tests.ps1 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Tests/Rules/AvoidPositionalParameters.tests.ps1 b/Tests/Rules/AvoidPositionalParameters.tests.ps1 index 95ddd6ef1..1e0000a54 100644 --- a/Tests/Rules/AvoidPositionalParameters.tests.ps1 +++ b/Tests/Rules/AvoidPositionalParameters.tests.ps1 @@ -37,12 +37,10 @@ Describe "AvoidPositionalParameters" { [Parameter(Position=2)]$B, [Parameter(Position=3)]$C) } - Foo "a" "b" "c" - } + Foo "a" "b" "c"} $warnings = Invoke-ScriptAnalyzer -ScriptDefinition "$sb" - $warnings.Count | Should -BeGreaterThan 0 - $warnings.RuleName | Should -Contain $violationName - $warnings.Message | Should -Contain "Cmdlet 'Foo' has positional parameter. Please use named parameters instead of positional parameters when calling a command." + $warnings.Count | Should -Be 1 + $warnings.RuleName | Should -BeExactly $violationName } } } From 479fbc4c542579325e8bca0dd0e87d4ded0cbc2b Mon Sep 17 00:00:00 2001 From: Klaudia Algiz Date: Thu, 17 May 2018 13:43:57 -0700 Subject: [PATCH 11/11] Code cleanup --- Engine/Helper.cs | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 7d425fd93..c86e2eb55 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -630,31 +630,21 @@ public bool PositionalParameterUsed(CommandAst cmdAst, bool moreThanTwoPositiona } // Because of the way we count, we will also count the cmdlet as an argument so we have to -1 - int argumentsWithoutProcedingParameters = -1; - bool parameterPreceding = false; + int argumentsWithoutProcedingParameters = 0; - foreach (CommandElementAst ceAst in cmdAst.CommandElements) - { - var cmdParamAst = ceAst as CommandParameterAst; - if (cmdParamAst != null) - { - parameterPreceding = true; - } else + var commandElementCollection = cmdAst.CommandElements; + for (int i = 1; i < commandElementCollection.Count(); i++) { + if (!(commandElementCollection[i] is CommandParameterAst) && !(commandElementCollection[i-1] is CommandParameterAst)) { - if (!parameterPreceding) - { - argumentsWithoutProcedingParameters += 1; - } - parameterPreceding = false; + argumentsWithoutProcedingParameters++; } } // if not the first element in a pipeline, increase the number of arguments by 1 PipelineAst parent = cmdAst.Parent as PipelineAst; - if (parent != null && parent.PipelineElements.Count > 1 && parent.PipelineElements[0] != cmdAst) { - argumentsWithoutProcedingParameters += 1; + argumentsWithoutProcedingParameters++; } return moreThanTwoPositional ? argumentsWithoutProcedingParameters > 2 : argumentsWithoutProcedingParameters > 0;