PowerShell / vscode-powershell

Provides PowerShell language and debugging support for Visual Studio Code
https://marketplace.visualstudio.com/items/ms-vscode.PowerShell
MIT License
1.69k stars 486 forks source link

Collapsing code within a function with help not working correctly. #2013

Closed ryanfog closed 5 years ago

ryanfog commented 5 years ago

Issue Type: Feature Request

This issue has to do with a function with help and it not collapsing correctly. For Example:

Function Get-Magic{
<#
.SYNOPSIS
Really great function
#>
    Param(
    [Parameter(Position = 1, Mandatory = $true)]
    [ValidateNotNullOrEmpty()]
        [String]$firstParameter
    )
        Do amazing stuff here
}

If you were to collapse that function it would collapse fine. If you wanted to comment out the entire function using #< it collapses to the help section SYNOPSIS which is incorrect.

Extension version: 2019.5.0 VS Code version: Code 1.35.0 (553cfb2c2205db5f15f3ee8395bbd5cf066d357d, 2019-06-04T01:17:12.481Z) OS version: Windows_NT x64 10.0.16299

rjmholt commented 5 years ago

If you wanted to comment out the entire function using #< it collapses to the help section SYNOPSIS which is incorrect.

Can you please provide an example of a script where you've done this (e.g a modification of your initial example with the new comment inserted) and describe the actual vs desired behaviour?

rkeithhill commented 5 years ago

I'm not sure that nested block comments are supported in PowerShell (it doesn't parse correctly). That is if you're doing what I think you're doing:

image

I suggest that you highlight the function in VSCode and press Ctrl+K, Ctrl+C to line comment out the function. Then you can collapse it:

image

rjmholt commented 5 years ago

Yeah in the first example the comment only goes from line 1 to line 6. Line 14 is just a line comment with > as the only character

ryanfog commented 5 years ago

Hopefully this helps illustrate the issue.

Full sample code Fullcode

This is correct Proper Collapse

This is correct Proper Collapse 2

This is wrong, it should have collapsed down to line 16. Improper Collapsing

rkeithhill commented 5 years ago

Do you see that red squiggle on line 15? That is an indication that this is invalid syntax. I'm pretty sure nesting block comments is not valid PowerShell syntax.

rjmholt commented 5 years ago

This is wrong, it should have collapsed down to line 16.

PowerShell doesn't recognise anything after that first #> as a comment (we don't actually calculate it that way, but we maintain fidelity to PowerShell).

If we take that script:

Function Get-Magic{
<#
.SYNOPSIS
Really great function
#>
    Param(
    [Parameter(Position = 1, Mandatory = $true)]
    [ValidateNotNullOrEmpty()]
        [String]$firstParameter
    )
        Test-ValidCommand
}

And comment it out the way you suggest, it should all be a comment and nothing should happen if we invoke it:

<#
Function Get-Magic{
<#
.SYNOPSIS
Really great function
#>
    Param(
    [Parameter(Position = 1, Mandatory = $true)]
    [ValidateNotNullOrEmpty()]
        [String]$firstParameter
    )
        Test-ValidCommand
}
#>

However, invoking it I get this output:

PS > ./ex.ps1
At ~/Documents/ex.ps1:13 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
+ CategoryInfo          : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken

This is because lines 10-15 are not commented out at all.

This can also be verified by inspecting the AST, which is the PowerShell parser's view of the script (I was going to use the { ... stuff ... }.Ast trick here, but it turns out the braces get in the way, so it has to be the hard way):

PS> $toks = $errs = $null
PS> $ast = [System.Management.Automation.Language.Parser]::ParseFile("$PWD/ex.ps1", [ref]$toks, [ref]$errs)
PS> $ast

Attributes         : {}
UsingStatements    : {}
ParamBlock         : Param(
                        [Parameter(Position = 1, Mandatory = $true)]
                        [ValidateNotNullOrEmpty()]
                             [String]$firstParameter
                        )
BeginBlock         :
ProcessBlock       :
EndBlock           : Param(
                        [Parameter(Position = 1, Mandatory = $true)]
                        [ValidateNotNullOrEmpty()]
                             [String]$firstParameter
                        )
                             Test-ValidCommand
DynamicParamBlock  :
ScriptRequirements :
Extent             : <#
                     Function Get-Magic{
                     <#
                     .SYNOPSIS
                     Really great function
                     #>
                        Param(
                        [Parameter(Position = 1, Mandatory = $true)]
                        [ValidateNotNullOrEmpty()]
                             [String]$firstParameter
                        )
                             Test-ValidCommand
                     }
                     #>

Parent             :

PS> $errs

Extent ErrorId         Message                                          IncompleteInput
------ -------         -------                                          ---------------
}      UnexpectedToken Unexpected token '}' in expression or statement.           False

Here you can see that:

  1. PowerShell sees the body of the function after the synopsis block as not commented out
  2. The parser has emitted an error, saying the } token at the end is not expected. This is because the opening { is commented out but this one is not.

Very few programming languages support nested comments, chiefly because it's traditionally been seen as unneeded complexity in what should be a fast and low-level functionality (lexing) and is something many IDEs etc don't have general support for (notice the highlighting in StackOverflow break for the nested comments in Swift). However a few modern languages from outside the C family do have it (e.g. Rust, Haskell, OCaml, Swift), chiefly for the reason you want it -- so you can comment out a block that already has a comment in it.

So anyway, our folding behaviour is by-design; if we folded as if PowerShell supported nested comments, it would be misleading at best.