diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f73be17..99af0c2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-24.04 strategy: matrix: - go: ["1.23", "1.22"] + go: ["1.23.3", "1.22.9"] env: GOTOOLCHAIN: local steps: @@ -28,11 +28,10 @@ jobs: uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - check-latest: true - name: 🧸 golangci-lint uses: golangci/golangci-lint-action@v6 with: - version: v1.61.0 + version: v1.62.0 - name: 🔨 Test run: | go get -C ./pkg/analyzer/testdata golang.org/x/exp/errors diff --git a/.golangci.yaml b/.golangci.yaml index 3f68612..0f79e7d 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -5,9 +5,7 @@ linters: enable-all: true disable: # deprecated - - execinquery - exportloopref - - gomnd # disabled - depguard - dupl @@ -52,3 +50,6 @@ issues: linters: - gocheckcompilerdirectives text: "go:debug" + - linters: + - govet + text: '^shadow: declaration of "(ctx|err|ok)" shadows declaration at line \d+$' diff --git a/go.mod b/go.mod index d99e41e..7699274 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ module fillmore-labs.com/zerolint -go 1.22.7 +go 1.22.9 -toolchain go1.23.1 +toolchain go1.23.3 -require golang.org/x/tools v0.25.0 +require golang.org/x/tools v0.27.0 require ( - golang.org/x/mod v0.21.0 // indirect - golang.org/x/sync v0.8.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/sync v0.9.0 // indirect ) diff --git a/go.sum b/go.sum index 6f1f712..394d668 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 481fc8d..8763170 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -33,6 +33,7 @@ can often be avoided.` var Analyzer = &analysis.Analyzer{ //nolint:gochecknoglobals Name: Name, Doc: Doc, + URL: "https://pkg.go.dev/fillmore-labs.com/zerolint/pkg/analyzer", Run: run, Requires: []*analysis.Analyzer{inspect.Analyzer}, } diff --git a/pkg/analyzer/testdata/go.mod b/pkg/analyzer/testdata/go.mod index 34d1fd1..18f6e6b 100644 --- a/pkg/analyzer/testdata/go.mod +++ b/pkg/analyzer/testdata/go.mod @@ -2,4 +2,4 @@ module go.test go 1.22 -require golang.org/x/exp/errors v0.0.0-20240823005443-9b4947da3948 +require golang.org/x/exp/errors v0.0.0-20241108190413-2d47ceb2692f diff --git a/pkg/analyzer/testdata/go.sum b/pkg/analyzer/testdata/go.sum index 8290f68..89aae2f 100644 --- a/pkg/analyzer/testdata/go.sum +++ b/pkg/analyzer/testdata/go.sum @@ -1,2 +1,2 @@ -golang.org/x/exp/errors v0.0.0-20240823005443-9b4947da3948 h1:IE9ZGXGK0A3EhE/vajvqwjYT5JsrZfxtVwBflW/O2vU= -golang.org/x/exp/errors v0.0.0-20240823005443-9b4947da3948/go.mod h1:YgqsNsAu4fTvlab/7uiYK9LJrCIzKg/NiZUIH1/ayqo= +golang.org/x/exp/errors v0.0.0-20241108190413-2d47ceb2692f h1:c+fBisNL7gIMeDtpC2uEtpqRl/MBKfCtkvXIH+N1kBk= +golang.org/x/exp/errors v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:3MJlzkbfWNENOrJtD7NDv3LJffbUe3TmEUCaeYRe+is= diff --git a/pkg/visitor/call.go b/pkg/visitor/call.go index d5f4229..79a5c7c 100644 --- a/pkg/visitor/call.go +++ b/pkg/visitor/call.go @@ -28,7 +28,7 @@ import ( // visitCallValue checks for encoding/json#Decoder.Decode, json.Unmarshal, errors.Is and errors.As. func (v Visitor) visitCallBasic(x *ast.CallExpr) bool { //nolint:cyclop - fun, ok := unwrap(x.Fun).(*ast.SelectorExpr) + fun, ok := ast.Unparen(x.Fun).(*ast.SelectorExpr) if !ok { return true } @@ -38,8 +38,8 @@ func (v Visitor) visitCallBasic(x *ast.CallExpr) bool { //nolint:cyclop return false // Do not report pointers in json.Decoder#Decode } - switch path, ok2 := v.pathOf(fun.X); { - case !ok2: + switch path, ok := v.pathOf(fun.X); { + case !ok: return true case path == "encoding/json" && fun.Sel.Name == "Unmarshal": @@ -105,7 +105,7 @@ func (v Visitor) visitCast(t types.Type, x *ast.CallExpr) bool { message := fmt.Sprintf("cast of nil to pointer to zero-size variable of type %q", elem) var fixes []analysis.SuggestedFix - if s, ok2 := unwrap(x.Fun).(*ast.StarExpr); ok2 { + if s, ok := ast.Unparen(x.Fun).(*ast.StarExpr); ok { fixes = v.makePure(x, s.X) } @@ -119,13 +119,13 @@ func (v Visitor) visitNew(x *ast.CallExpr) bool { if len(x.Args) != 1 { return true } - fun, ok := unwrap(x.Fun).(*ast.Ident) + fun, ok := ast.Unparen(x.Fun).(*ast.Ident) if !ok || fun.Name != "new" { return true } arg := x.Args[0] // new(arg). - argType := v.TypesInfo.Types[arg].Type + argType := v.TypesInfo.TypeOf(arg) if !v.zeroSizedType(argType) { return true } @@ -137,20 +137,6 @@ func (v Visitor) visitNew(x *ast.CallExpr) bool { return false } -// unwrap removes parentheses from an expression (x). -func unwrap(e ast.Expr) ast.Expr { - x := e - for { - p, ok := x.(*ast.ParenExpr) - if !ok { - break - } - x = p.X - } - - return x -} - // makePure adds a suggested fix from (*T)(nil) or new(T) to T{}. func (v Visitor) makePure(n ast.Node, x ast.Expr) []analysis.SuggestedFix { var buf bytes.Buffer diff --git a/pkg/visitor/func.go b/pkg/visitor/func.go index a5d1339..c59ae9a 100644 --- a/pkg/visitor/func.go +++ b/pkg/visitor/func.go @@ -31,14 +31,14 @@ func (v Visitor) visitFunc(x *ast.FuncDecl) bool { } recv := x.Recv.List[0] - recvType := v.TypesInfo.Types[recv.Type].Type + recvType := v.TypesInfo.TypeOf(recv.Type) elem, ok := v.zeroSizedTypePointer(recvType) if !ok { // Not a pointer receiver or no pointer to a zero-sized type. return true } var fixes []analysis.SuggestedFix - if s, ok2 := recv.Type.(*ast.StarExpr); ok2 { + if s, ok := recv.Type.(*ast.StarExpr); ok { fixes = v.removeOp(s, s.X) } diff --git a/pkg/visitor/star.go b/pkg/visitor/star.go index e8f1147..41652e5 100644 --- a/pkg/visitor/star.go +++ b/pkg/visitor/star.go @@ -25,7 +25,7 @@ import ( // visitUnary checks expressions in form *x. func (v Visitor) visitStar(x *ast.StarExpr) bool { // *... - t := v.TypesInfo.Types[x.X].Type + t := v.TypesInfo.TypeOf(x.X) var message string if p, ok := t.Underlying().(*types.Pointer); ok { if !v.zeroSizedType(p.Elem()) { diff --git a/pkg/visitor/unary.go b/pkg/visitor/unary.go index 2fc7496..aab45bb 100644 --- a/pkg/visitor/unary.go +++ b/pkg/visitor/unary.go @@ -29,7 +29,7 @@ func (v Visitor) visitUnary(x *ast.UnaryExpr) bool { } // &... - t := v.TypesInfo.Types[x.X].Type + t := v.TypesInfo.TypeOf(x.X) if !v.zeroSizedType(t) { return true } diff --git a/pkg/visitor/visitor.go b/pkg/visitor/visitor.go index 22fe373..f73c8e4 100644 --- a/pkg/visitor/visitor.go +++ b/pkg/visitor/visitor.go @@ -81,12 +81,12 @@ func (v Run) visitFunc() ([]ast.Node, func(ast.Node, bool) bool) { } // visitBasic is the main functions called by inspector.Nodes for basic analysis. -func (v Visitor) visitBasic(n ast.Node, push bool) bool { +func (v Visitor) visitBasic(x ast.Node, push bool) bool { if !push { return true } - switch x := n.(type) { + switch x := x.(type) { case *ast.BinaryExpr: return v.visitBinary(x) @@ -105,12 +105,12 @@ func (v Visitor) visitBasic(n ast.Node, push bool) bool { } // visit is the main functions called by inspector.Nodes for full analysis. -func (v Visitor) visit(n ast.Node, push bool) bool { +func (v Visitor) visit(x ast.Node, push bool) bool { if !push { return true } - switch x := n.(type) { + switch x := x.(type) { case *ast.StarExpr: return v.visitStar(x)