Fixer/Command/CommandPositionalParameter/CommandPositionalParameter.ps1
& { Set-StrictMode -Off $commands = @{} # get all commands available foreach($command in (Get-Command -CommandType Function, Cmdlet)) { # add each unique command to a hash table $name = $command.Name if ($commands.ContainsKey($name) -eq $false) { $commands.Add($name, $command) } } # get all commands found in script $items = [ISESteroids.SteroidsFixer.Helpers]::GetAST('Command') $SplattedItems = @() # examine each command found in script :outer foreach($item in $items) { $namedparameters = @{} $positionalparameters = @{} # get command name... $CommandName = $item.CommandElements[0].Extent.Text # ...is it known? if ($commands.ContainsKey($CommandName)) { # yes, check parameter definitions $Command = $commands[$CommandName] if ($Command.Parameters -ne $null) { # identify parameters used in the command $position = 0 $elements = $item.CommandElements.Count -1 for($i=1; $i -le $elements; $i++) { $element = $item.CommandElements[$i] # is it a non-splatted parameter? if ($element -is [System.Management.Automation.Language.CommandParameterAst]) { # look up the parameter in the parameter definition $parameterName = $element.ParameterName $ParameterObject = $null if ($command.Parameters.ContainsKey($parameterName) -eq $false) { # not found, is it a dynamic parameter? $ParameterName = ($command.Parameters.Values | Where-Object { $_.isDynamic -eq $false } | Select-Object -ExpandProperty Name) -like "$ParameterName*" if ($command.Parameters.ContainsKey($parameterName) -eq $false) { continue outer } } # static parameter $ParameterObject = $Command.Parameters[$ParameterName] if ($ParameterObject.SwitchParameter -eq $false) { # no switch parameter $namedparameters.Add($ParameterName, $item.CommandElements[$i+1]) $i++ } else { # switch parameter $namedparameters.Add($parameterName, $null) } } else { # is it a splatted parameter? if ($item.CommandElements[$i] -is [System.Management.Automation.Language.VariableExpressionAst] -and $item.CommandElements[$i].Splatted ) { $SplattedItems += $position } $positionalparameters.Add($position, $item.CommandElements[$i]) $position++ } } } # identify the correct parameterset $validSets = :setloop foreach($set in $Command.ParameterSets) { # all named parameters must be in foreach($par in $namedparameters.Keys) { if ($set.Parameters.Name -contains $par -eq $false) { continue setloop } } $set } if ($validSets.Count -eq 0) { continue outer } :parameterSets foreach($set in ($validSets | Sort-Object { $_.IsDefault } -Descending)) { # find positional parameters $changes = @() $shift = 0 foreach($parameter in ($set.Parameters | Sort-Object -Property Position)) { $position = $parameter.Position if ($position -ge 0) { $name = $parameter.Name if ($namedparameters.ContainsKey($name)) { $shift-- } else { $realposition = $position + $shift # if a paremeter takes values from remaining arguments, then do not turn it into a named parameter if ($positionalparameters.ContainsKey($realposition) -and ($parameter.ValueFromRemainingArguments -eq $false -or ($positionalparameters.Count -lt 2))) { # does the data type fit? $skip = $false if ($validSets.Count -eq 1) { # one set remaining, do always } elseif ($positionalparameters[$realposition].GetType() -eq [System.Management.Automation.Language.ScriptBlockExpressionAst]) { if ($parameter.ParameterType -ne [ScriptBlock] -and $parameter.ParameterType -ne [ScriptBlock[]]) { $changes = @() continue parameterSets } } elseif ($positionalparameters[$realposition].GetType() -eq [System.Management.Automation.Language.StringConstantExpressionAst]) { if ($parameter.ParameterType -ne [String] -and $parameter.ParameterType -ne [String[]] -and $parameter.ParameterType -ne [Object] -and $parameter.ParameterType -ne [Object[]]) { $changes = @() continue parameterSets } } elseif ($positionalparameters[$realposition].GetType() -eq [System.Management.Automation.Language.ParenExpressionAst]) { if ($parameter.ParameterType -ne [Object] -and $parameter.ParameterType -ne [Object[]]) { $changes = @() continue parameterSets } } elseif ($positionalparameters[$realposition].GetType() -eq [System.Management.Automation.Language.ArrayLiteralAst]) { if ($parameter.ParameterType -ne [Object] -and $parameter.ParameterType -ne [Object[]]) { $changes = @() continue parameterSets } } elseif ($positionalparameters[$realposition].GetType() -eq [System.Management.Automation.Language.VariableExpressionAst]) { if ($parameter.ParameterType -ne $positionalparameters[$realposition].StaticType -and $parameter.ParameterType.GetElementType() -ne $positionalparameters[$realposition].StaticType) { $changes = @() continue parameterSets } } else { $i = 1 } if ($skip -eq $false) { if ($SplattedItems -notcontains $realposition) { $changes += 1 $padding = ' ' $statement = $positionalparameters[$realposition].Parent $offset = $positionalparameters[$realposition].Extent.StartOffset - $statement.Extent.StartOffset if ($statement.Extent.Text.SubString($offset-1, 1) -eq ' ') { $padding = '' } $changes[$changes.Count-1] = @($positionalparameters[$realposition].Extent.StartOffset, $positionalparameters[$realposition].Extent.StartOffset, ($padding + '-' + $parameter.Name + ' ')) } } } } } } foreach($change in $changes) { [ISESteroids.SteroidsFixer.Helpers]::AddTextChange($change[0], $change[1], $change[2]) } break } } } Invoke-SteroidsTextChange } |