From 9cbb1efa7745c5ef9f82214d19eb3540decd05de Mon Sep 17 00:00:00 2001 From: Ainar Garipov Date: Tue, 22 Dec 2020 23:31:26 +0300 Subject: [PATCH] internal/lsp/source: add the shadow analyzer Fixes golang/go#43245 Change-Id: I4b51d8bfcb815c29339754637114558c62b0f6bd Reviewed-on: https://go-review.googlesource.com/c/tools/+/279395 Run-TryBot: Rebecca Stambler gopls-CI: kokoro TryBot-Result: Go Bot Trust: Robert Findley Trust: Rebecca Stambler Reviewed-by: Rebecca Stambler --- gopls/doc/analyzers.md | 25 +++++++++++++++++++++++++ internal/lsp/source/options.go | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md index dcfad5eb0b..78c9eb95eb 100644 --- a/gopls/doc/analyzers.md +++ b/gopls/doc/analyzers.md @@ -427,6 +427,31 @@ This is one of the simplifications that "gofmt -s" applies. Default value: `true`. +### **shadow** + +check for shadowed variables. A shadowed variable is a variable +declared in an inner scope with the same name and type as a variable in +an outer scope, and where the outer variable is mentioned after the +inner one is declared. + +For example: + +```go +func BadRead(f *os.File, buf []byte) error { + var err error + for { + n, err := f.Read(buf) // shadows the function variable 'err' + if err != nil { + break // causes return of wrong value + } + foo(buf) + } + return err +} +``` + +Default value: `false`. + ### **simplifyslice** check for slice simplifications diff --git a/internal/lsp/source/options.go b/internal/lsp/source/options.go index a8021f8a33..6c158b8641 100644 --- a/internal/lsp/source/options.go +++ b/internal/lsp/source/options.go @@ -32,6 +32,7 @@ import ( "golang.org/x/tools/go/analysis/passes/lostcancel" "golang.org/x/tools/go/analysis/passes/nilfunc" "golang.org/x/tools/go/analysis/passes/printf" + "golang.org/x/tools/go/analysis/passes/shadow" "golang.org/x/tools/go/analysis/passes/shift" "golang.org/x/tools/go/analysis/passes/sortslice" "golang.org/x/tools/go/analysis/passes/stdmethods" @@ -582,7 +583,6 @@ func (o *Options) ForClientCapabilities(caps protocol.ClientCapabilities) { o.SemanticMods = caps.TextDocument.SemanticTokens.TokenModifiers // we don't need Requests, as we support full functionality // we don't need Formats, as there is only one, for now - } func (o *Options) Clone() *Options { @@ -1054,6 +1054,7 @@ func defaultAnalyzers() map[string]Analyzer { atomicalign.Analyzer.Name: {Analyzer: atomicalign.Analyzer, Enabled: true}, deepequalerrors.Analyzer.Name: {Analyzer: deepequalerrors.Analyzer, Enabled: true}, fieldalignment.Analyzer.Name: {Analyzer: fieldalignment.Analyzer, Enabled: false}, + shadow.Analyzer.Name: {Analyzer: shadow.Analyzer, Enabled: false}, sortslice.Analyzer.Name: {Analyzer: sortslice.Analyzer, Enabled: true}, testinggoroutine.Analyzer.Name: {Analyzer: testinggoroutine.Analyzer, Enabled: true}, unusedparams.Analyzer.Name: {Analyzer: unusedparams.Analyzer, Enabled: false},