Skip to content

powershell.codeFormatting.whitespaceBetweenParameters inappropriately removes + operators in string concatenation #1536

Description

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

Activity

rjmholt commented on Jul 1, 2020

@rjmholt
Contributor

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

bergmeister commented on Jul 1, 2020

@bergmeister
Collaborator

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

rjmholt commented on Jul 1, 2020

@rjmholt
Contributor
> 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

bergmeister commented on Jul 20, 2020

@bergmeister
Collaborator

Rob Holt (@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.

rjmholt commented on Jul 20, 2020

@rjmholt
Contributor

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

I trust you on this

ninmonkey commented on Jul 25, 2020

@ninmonkey

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"
}
ghost closed this as completedon Aug 1, 2020

mmunchandersen commented on Nov 18, 2020

@mmunchandersen

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions