Skip to content

Commit

Permalink
gopls: add and enable the slog analyzer
Browse files Browse the repository at this point in the history
This analyzer is included in go/vet, and so gopls should have it as
well.

Change-Id: Ib5cbee44a1f38c4aa45d75bcaa7a345d88099d8e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/524764
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
  • Loading branch information
findleyr authored and gopherbot committed Sep 1, 2023
1 parent 2c6ba93 commit 44f7796
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
18 changes: 18 additions & 0 deletions gopls/doc/analyzers.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,24 @@ This is one of the simplifications that "gofmt -s" applies.

**Enabled by default.**

## **slog**

check for invalid structured logging calls

The slog checker looks for calls to functions from the log/slog
package that take alternating key-value pairs. It reports calls
where an argument in a key position is neither a string nor a
slog.Attr, and where a final key is missing its value.
For example,it would report

slog.Warn("message", 11, "k") // slog.Warn arg "11" should be a string or a slog.Attr

and

slog.Info("message", "k1", v1, "k2") // call to slog.Info missing a final value

**Enabled by default.**

## **sortslice**

check the argument type of sort.Slice
Expand Down
11 changes: 11 additions & 0 deletions gopls/internal/lsp/source/api_json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions gopls/internal/lsp/source/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"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/slog"
"golang.org/x/tools/go/analysis/passes/sortslice"
"golang.org/x/tools/go/analysis/passes/stdmethods"
"golang.org/x/tools/go/analysis/passes/stringintconv"
Expand Down Expand Up @@ -1549,6 +1550,7 @@ func defaultAnalyzers() map[string]*Analyzer {
nilfunc.Analyzer.Name: {Analyzer: nilfunc.Analyzer, Enabled: true},
printf.Analyzer.Name: {Analyzer: printf.Analyzer, Enabled: true},
shift.Analyzer.Name: {Analyzer: shift.Analyzer, Enabled: true},
slog.Analyzer.Name: {Analyzer: slog.Analyzer, Enabled: true},
stdmethods.Analyzer.Name: {Analyzer: stdmethods.Analyzer, Enabled: true},
stringintconv.Analyzer.Name: {Analyzer: stringintconv.Analyzer, Enabled: true},
structtag.Analyzer.Name: {Analyzer: structtag.Analyzer, Enabled: true},
Expand Down
23 changes: 21 additions & 2 deletions gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt
Original file line number Diff line number Diff line change
@@ -1,32 +1,51 @@
Test of warning diagnostics from various analyzers:
tests, copylocks, printf, and timeformat.
copylocks, printf, slog, tests, and timeformat.

-- go.mod --
module example.com
go 1.12

-- flags --
-min_go=go1.21

-- bad_test.go --
package analyzer

import (
"fmt"
"log/slog"
"sync"
"testing"
"time"
)

func Testbad(t *testing.T) { //@diag("", re"Testbad has malformed name: first letter after 'Test' must not be lowercase")
// copylocks
func _() {
var x sync.Mutex
_ = x //@diag("x", re"assignment copies lock value to _: sync.Mutex")
}

// printf
func _() {
printfWrapper("%s") //@diag(re`printfWrapper\(.*\)`, re"example.com.printfWrapper format %s reads arg #1, but call has 0 args")
}

func printfWrapper(format string, args ...interface{}) {
fmt.Printf(format, args...)
}

// slog
func _() {
slog.Info("msg", 1) //@diag("1", re`slog.Info arg "1" should be a string or a slog.Attr`)
}

// tests
func Testbad(t *testing.T) { //@diag("", re"Testbad has malformed name: first letter after 'Test' must not be lowercase")
}

// timeformat
func _() {
now := time.Now()
fmt.Println(now.Format("2006-02-01")) //@diag("2006-02-01", re"2006-02-01 should be 2006-01-02")
}

0 comments on commit 44f7796

Please sign in to comment.