Skip to content

Warning about unused variable in VSCode #827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
olegstrutinskii opened this issue Oct 27, 2017 · 11 comments · Fixed by #935
Closed

Warning about unused variable in VSCode #827

olegstrutinskii opened this issue Oct 27, 2017 · 11 comments · Fixed by #935

Comments

@olegstrutinskii
Copy link

A wrong warning about unused variable, but that variable used later in code:

default

@CJHarmath
Copy link

+1
I've seen this as well with Insiders build + latest everything. But it's not consistent and sometimes I just have to restart the powershell session

@TylerLeonhardt
Copy link
Member

I tried running Script Analyzer on its own against the original repro and I'm seeing the warning. Here's the repro:

In the file repro.ps1:

$a = 0
$b = @(1, 2)
$b | ForEach-Object {
    $a += 1
}
Write-Host $a

in a terminal:

Install-Module -Name PSScriptAnalyzer

Invoke-ScriptAnalyzer -Path path/to/repro.ps1 -Settings PSGallery -Recurse

The output:

RuleName                            Severity     ScriptName Line  Message
--------                            --------     ---------- ----  -------
PSUseDeclaredVarsMoreThanAssignment Warning      repro2.ps1 4     The variable 'a' is assigned but never used.

@mattmcnabb
Copy link
Contributor

I think this warning is appropriate. In your example, $a in the original assignment and the $a inside the foreach block are in two different scopes. Try this:

$a = 1

& {
    $a = 2
}

$a

image

I don't believe there is an accurate way for PSScriptAnalyzer to guess that your intention is to use the $a variable in the parent scope, and it has to assume that you have assigned an unused variable.

@bergmeister
Copy link
Collaborator

bergmeister commented Feb 6, 2018

There are various issues with false positives of this rule that would probably need to be re-written from the ground up using a different technique to overcome its limitations. I plan to collate all those issues in a meta-issue at some point.

@uSlackr
Copy link

uSlackr commented May 29, 2018

Here is my example. $RemoveCount is reported as unused. $RemoveError is not

main loopk in code. Calls functions Remove-member() and Write-Log()

$BaseDir = "C:\Temp\attest"
get-childitem $BaseDir*AttestListing.csv | foreach {
$CSVfile=$

write-log "Processing data file: $($CSVfile.name)" -verbose
$RemoveCount = 0
$RemoveError = $false
import-csv $CSVfile |foreach{
    $line = $_
    if ($line."Remove Member?" -match "[yYxX]") {
        echo "Removing $($line."Member Name") from $($line."Group Name")"
        #write-log "Removing $("$_.Member Name") from $("$_.Group Name")" -verbose
        If (Remove-Member($line)) {
            $RemoveCount = $RemoveCount + 1
        } else {
            $RemoveError = $true
        }
        
    }
}
if ($RemoveError -eq $true){
    Write-log "Error processing changes for: $($CSVFile.fullname)" -verbose
    # If error removing, file is not renamed and must be processed manually
 } else {

    if ($RemoveCount -eq 0) {
        Write-log "No changes processed for $($CSVFile.fullname)" -verbose
    }Else { 
        Write-log "$RemoveCount members removed from $($CSVFile.fullname)" -verbose
    }

    Try {
        Rename-item $CSVfile.fullname "$($CSVFile.basename)_processed.csv"
    }
    Catch {}
}

}

@GuyWicks
Copy link

+1

The directive to suppress messages also does not work:

[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments","")]

$smtpserver_a = "smtp.example.com"
$smtpserver_b = "smtp.example.com"  < error
$smtpserver_c = "smtp.example.com"  < error
$smtpserver_d = "smtp.example.com"  < error

Anyone know how to suppress this in the visual code settings?

@bergmeister
Copy link
Collaborator

bergmeister commented May 30, 2018

@GuyWicks Your example case already got fixed in PR #836 and will be in the upcoming release of 1.17 that is hopefully going to be released in the next days.
The Suppressionattribute needs to be on a function or Param() block in order to work.
VsVode has a setting to define a relative path to a PSSA settings file where you can define and customize the rules to be used inside VSCode. I would not recommend turning off this rule though because it is still useful despite some false positives. Most warnings produced by different code analysis tools needs human judgement, please keep that in mind. It is always a trade off between being able to determine 100% that something is wrong and warning on the possibility that something could be wrong.

@GuyWicks
Copy link

Thanks for this.

For future reference, this now works as I expected:

[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments","")]
param()

$smtpserver_a = "smtp.example.com"  # no error
$smtpserver_b = "smtp.example.com"  # no error
$smtpserver_c = "smtp.example.com"  # no error
$smtpserver_d = "smtp.example.com"  #no error

Agree with your recommendation to use this suppression with caution - in my particular use-case I have a common file that stores global configuration variables so these are not used in this file, but in other files. You may legitimately criticise this design model :)

@crossan007
Copy link

If the warning appears in variables you're referencing inside a Foreach-Object, or other construct, then specifying a scope on the variable seems to appease the warning.

To borrow/modify @mattmcnabb's example:

$a = 1

& {
    $script:a = 2
}

$a

I don't believe there is an accurate way for PSScriptAnalyzer to guess that your intention is to use the $a variable in the parent scope, and it has to assume that you have assigned an unused variable.

I think that method is $script: (or global, or local): https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-6

@cawoodm
Copy link

cawoodm commented Nov 23, 2020

This is definitely still an issue in the latest VSCode v1.51.1

image

@vivere-dally
Copy link

vivere-dally commented Mar 8, 2021

I ran into this warning with ForEach-Object's Script Blocks:

$foo= 1..10 | ForEach-Object -Begin { $i = 1; $bar= @{}; } -End { $bar; } -Process {
    $bar["p$i"] = $_
    $i++
}

Shows warning: $i and $nums unused.

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