Psscriptanalyzer: powershell.codeFormatting.whitespaceBetweenParameters inappropriately removes + operators in string concatenation

Created on 1 Jul 2020  Â·  7Comments  Â·  Source: PowerShell/PSScriptAnalyzer

Issue Description

When formatting a document with powershell.codeFormatting.whitespaceBetweenParameters enabled, the formatter inappropriately removes + operators in string concatenation.

Steps to reproduce:

  1. Enter this code example: Write-Output ($env:computername + ", " + $env:username) (GitHub is collapsing the whitespace, but there are four spaces on each side of each plus sign)
  2. Enable powershell.codeFormatting.whitespaceBetweenParameters
  3. Format document

Expected result:

Write-Output ($env:computername + ", " + $env:username)

Actual result:

Write-Output ($env:computername ", " + $env:username) (which is syntactically invalid!)

Additionally, if you start out with the expected result and format the document, you get the following result:

Write-Output ($env:computername ", " $env:username) ...which is even worse, as the operators have been removed entirely.

Attached Logs

1593619176-7b7e0c1b-7340-41cb-a9a0-c526c1c513bd1593619173652.zip
editor services.log

Environment Information

Visual Studio Code

| Name | Version |
| --- | --- |
| Operating System | Windows_NT x64 10.0.19041 |
| VSCode | 1.46.1|
| PowerShell Extension Version | 2020.6.0 |

PowerShell Information

|Name|Value|
|---|---|
|PSVersion|5.1.19041.1|
|PSEdition|Desktop|
|PSCompatibleVersions|1.0 2.0 3.0 4.0 5.0 5.1.19041.1|
|BuildVersion|10.0.19041.1|
|CLRVersion|4.0.30319.42000|
|WSManStackVersion|3.0|
|PSRemotingProtocolVersion|2.3|
|SerializationVersion|1.1.0.1|

Visual Studio Code Extensions

Visual Studio Code Extensions(Click to Expand)

|Extension|Author|Version|
|---|---|---|
|powershell|ms-vscode|2020.6.0|

Area - Formatter Issue - Bug Resolution - Fixed

All 7 comments

Reproduces with:

Invoke-Formatter -ScriptDefinition 'Write-Output ($env:computername + ", " + $env:username)' -Settings @{
 Rules = @{
   PSUseConsistentWhitespace = @{
     Enable = $true
     CheckParameter = $true
   }
  }
}

in PSSA 1.19.

Transferring to the PSScriptAnalyzer repo

@rjmholt Can you reproduce with the latest master? This issue was probably already fixed in PR #1498

> pwsh-preview.cmd
PowerShell 7.1.0-preview.5
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

C:\Users\Robert Holt\Documents\Dev\Microsoft\PSScriptAnalyzer [master ≡ +3 ~0 -0 !]
> gmo PSSCriptAnalyzer
C:\Users\Robert Holt\Documents\Dev\Microsoft\PSScriptAnalyzer [master ≡ +3 ~0 -0 !]
> ipmo .\out\PSScriptAnalyzer\
C:\Users\Robert Holt\Documents\Dev\Microsoft\PSScriptAnalyzer [master ≡ +3 ~0 -0 !]
> Invoke-Formatter -ScriptDefinition 'Write-Output ($env:computername + ", " + $env:username)' -Settings @{
>>  Rules = @{
>>    PSUseConsistentWhitespace = @{
>>      Enable = $true
>>      CheckParameter = $true
>>    }
>>   }
>> }
Write-Output ($env:computername ", " + $env:username)

Looks like I can unfortunately

@rjmholt Are you sure you have pulled all changes in? I can reproduce with 1.19.0 but not with the latest version of master.

I can reproduce with 1.19.0 but not with the latest version of master.

I trust you on this

keyword process is being deleted by whitespaceBetweenParameters

Although this code has a syntax error -- I thought It was still worth noting because:

  • there are no whitespace/parameters involved
  • it breaks the language keyword named process. Should that be allowed?
  • if it's invalid grammar/syntax, shouldn't the formatter complain, instead of applying edits?

the tooltip mentions the alias process. I don't have one default profiles for Powershell 7.0.3 and Windows Powershell 5.1.18

I was curious if the keyword could be aliased:

# does not complain
New-Alias -Name 'process' -Value Get-ChildItem -Verbose -Debug

# this expects more input, it's not using alias
PS> process
>> 
>>
# Ctrl+C

# this isn't either
process .

ParserError: 
Line |
   1 |  process .
     |         ~
     | Missing statement block after 'process'.

test cases that break

meaning process { } is replaced with Get-Process { }

function ErrorCase1 {
    [CmdletBinding()]

    begin {}
    Process {}
}

function ErrorCase2 {
    [CmdletBinding()]
    param()

    $x = 1
    process {}
}
function ErrorCase3 {
    [CmdletBinding()]
    param()
    ''
    process {}
}

function e4 {
    ''
    process {}
}

working case

function GoodCase1 {
    # this works
    begin {}
    Process {}
}
function GoodCase2 {
    # this works
    [CmdletBinding()]
    param()

    begin {}
    Process {}
}
> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.0.3
PSEdition                      Core 
GitCommitId                    7.0.3
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}       
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0


> (Get-Module -ListAvailable PSScriptAnalyzer).Version | ForEach-Object { $_.ToString() }

1.19.0

editor services.log

{
    "[powershell]": {
        "editor.formatOnSave": false,
        "editor.formatOnPaste": false,
        "editor.autoIndent": "advanced",
        "editor.formatOnType": true,
        "files.autoGuessEncoding": false,
        "files.encoding": "utf8bom"
    },
    "diffEditor.ignoreTrimWhitespace": true,
    "editor.formatOnPaste": true,
    "editor.formatOnSave": true,
    "editor.formatOnType": true,
    "editor.renderWhitespace": "none",
    "editor.trimAutoWhitespace": true,
    "files.trimTrailingWhitespace": true,
    "powershell editor services.trace.server": "verbose",
    "powershell.buttons.showPanelMovementButtons": true,
    "powershell.buttons.showRunButtons": true,
    "powershell.codeFolding.enable": true,
    "powershell.codeFolding.showLastLine": true,
    "powershell.codeFormatting.addWhitespaceAroundPipe": true,
    "powershell.codeFormatting.autoCorrectAliases": true,
    "powershell.codeFormatting.ignoreOneLineBlock": true,
    "powershell.codeFormatting.pipelineIndentationStyle": "None",
    "powershell.codeFormatting.preset": "OTBS",
    "powershell.codeFormatting.useCorrectCasing": true,
    "powershell.codeFormatting.whitespaceBetweenParameters": true,   // breaks
    // "powershell.codeFormatting.whitespaceBetweenParameters": false, // works
    "powershell.developer.editorServicesLogLevel": "Diagnostic",
    "powershell.enableProfileLoading": true,
    "powershell.integratedConsole.suppressStartupBanner": false,
    "python.formatting.provider": "black",
    "workbench.editor.labelFormat": "medium"
}

The issue has re-appeared in my setup (see below):

when I set:

"powershell.codeFormatting.whitespaceBetweenParameters": true

then

"Write-Output ($env:computername + ", " + $env:username)"
is formatted to:
"Write-Output ($env:computername ", " $env:username)"

The formatting does not happen when I set "powershell.codeFormatting.whitespaceBetweenParameters": false

The only thing I can think of is that I upgraded to powershell core 7.1

My setup:
Version: 1.51.1 (user setup)
Commit: e5a624b788d92b8d34d1392e4c4d9789406efe8f
Date: 2020-11-10T23:34:32.027Z
Electron: 9.3.3
Chrome: 83.0.4103.122
Node.js: 12.14.1
V8: 8.3.110.13-electron.0
OS: Windows_NT x64 10.0.19042

Name: PowerShell
Id: ms-vscode.powershell
Description: (Preview) Develop PowerShell scripts in Visual Studio Code!
Version: 2020.6.0
Publisher: Microsoft
VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andrewducker picture andrewducker  Â·  6Comments

juneb picture juneb  Â·  7Comments

chriskuech picture chriskuech  Â·  6Comments

ShaydeNofziger picture ShaydeNofziger  Â·  4Comments

iainbrighton picture iainbrighton  Â·  3Comments