diff --git a/go.mod b/go.mod index fefec0ee..87312393 100644 --- a/go.mod +++ b/go.mod @@ -151,10 +151,11 @@ require ( github.com/gofrs/flock v0.13.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golangci/asciicheck v0.5.0 // indirect + github.com/golangci/canonicalheader v0.0.0-20260827115959-a25c71c521f6 // indirect github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 // indirect github.com/golangci/go-printf-func-name v0.1.1 // indirect github.com/golangci/gofmt v0.0.0-20260820135601-e84e05053792 // indirect - github.com/golangci/golangci-lint/v2 v2.13.1 // indirect + github.com/golangci/golangci-lint/v2 v2.13.2 // indirect github.com/golangci/golines v0.15.0 // indirect github.com/golangci/misspell v0.8.0 // indirect github.com/golangci/plugin-module-register v0.1.2 // indirect @@ -186,7 +187,6 @@ require ( github.com/klauspost/compress v1.19.1 // indirect github.com/kulti/thelper v0.7.1 // indirect github.com/kunwardeep/paralleltest v1.0.15 // indirect - github.com/lasiar/canonicalheader v1.1.2 // indirect github.com/ldez/exptostd v0.4.5 // indirect github.com/ldez/gomoddirectives v0.9.0 // indirect github.com/ldez/grignotin v0.10.1 // indirect @@ -280,7 +280,7 @@ require ( github.com/ultraware/funlen v0.2.0 // indirect github.com/ultraware/whitespace v0.2.0 // indirect github.com/uudashr/gocognit v1.2.1 // indirect - github.com/uudashr/iface v1.5.0 // indirect + github.com/uudashr/iface v1.5.1 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xen0n/gosmopolitan v1.3.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect @@ -315,7 +315,7 @@ require ( google.golang.org/protobuf v1.36.12 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.8.0 // indirect + honnef.co/go/tools v0.8.1 // indirect mvdan.cc/gofumpt v0.11.0 // indirect - mvdan.cc/unparam v0.0.0-20260818115549-3f964bcb5673 // indirect + mvdan.cc/unparam v0.0.0-20260823230713-2fa3d841b0c8 // indirect ) diff --git a/go.sum b/go.sum index 83540d79..5e3ffcc3 100644 --- a/go.sum +++ b/go.sum @@ -361,14 +361,16 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golangci/asciicheck v0.5.0 h1:jczN/BorERZwK8oiFBOGvlGPknhvq0bjnysTj4nUfo0= github.com/golangci/asciicheck v0.5.0/go.mod h1:5RMNAInbNFw2krqN6ibBxN/zfRFa9S6tA1nPdM0l8qQ= +github.com/golangci/canonicalheader v0.0.0-20260827115959-a25c71c521f6 h1:fVLolA3dG6s0brGetsiDAtcnpMSwVa2LqXJEw/9RJG4= +github.com/golangci/canonicalheader v0.0.0-20260827115959-a25c71c521f6/go.mod h1:1xo+NFW5S+bEf2DKXhaxuzvcDN5AR6o/KMwvqC5Mkpo= github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 h1:CbTB8KpqnViI6lIXxp03Oclc4VFHi3K4BWC1TacsZ+A= github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E= github.com/golangci/go-printf-func-name v0.1.1 h1:hIYTFJqAGp1iwoIfsNTpoq1xZAarogrvjO9AfiW3B4U= github.com/golangci/go-printf-func-name v0.1.1/go.mod h1:Es64MpWEZbh0UBtTAICOZiB+miW53w/K9Or/4QogJss= github.com/golangci/gofmt v0.0.0-20260820135601-e84e05053792 h1:WL8YKrt3UbOBqSRU7GpP5BTtQTMWtVtj+mfPijgZeIg= github.com/golangci/gofmt v0.0.0-20260820135601-e84e05053792/go.mod h1:te5hX0dW4C5r6YbXs+6ysNr8Q5UTmdIqGbb+mlFiYmA= -github.com/golangci/golangci-lint/v2 v2.13.1 h1:RuM4OcluM4xFQcGuRE6R7jA33pqxK/W1EsBxpugdZjg= -github.com/golangci/golangci-lint/v2 v2.13.1/go.mod h1:HwX7mDzqHbcSxlhrTygjX1GJbAfQ3sJAqOx41qQlhDE= +github.com/golangci/golangci-lint/v2 v2.13.2 h1:bCyq3E4vo9qwzifjpzJqYndEt7Ncva80qkk8G2B4TXU= +github.com/golangci/golangci-lint/v2 v2.13.2/go.mod h1:5xaMd1kAxV7GSBPEyngw8gnnjoRocqW9UVKdBR6627w= github.com/golangci/golines v0.15.0 h1:Qnph25g8Y1c5fdo1X7GaRDGgnMHgnxh4Gk4VfPTtRx0= github.com/golangci/golines v0.15.0/go.mod h1:AZjXd23tbHMpowhtnGlj9KCNsysj72aeZVVHnVcZx10= github.com/golangci/misspell v0.8.0 h1:qvxQhiE2/5z+BVRo1kwYA8yGz+lOlu5Jfvtx2b04Jbg= @@ -467,8 +469,6 @@ github.com/kulti/thelper v0.7.1 h1:fI8QITAoFVLx+y+vSyuLBP+rcVIB8jKooNSCT2EiI98= github.com/kulti/thelper v0.7.1/go.mod h1:NsMjfQEy6sd+9Kfw8kCP61W1I0nerGSYSFnGaxQkcbs= github.com/kunwardeep/paralleltest v1.0.15 h1:ZMk4Qt306tHIgKISHWFJAO1IDQJLc6uDyJMLyncOb6w= github.com/kunwardeep/paralleltest v1.0.15/go.mod h1:di4moFqtfz3ToSKxhNjhOZL+696QtJGCFe132CbBLGk= -github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4= -github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI= github.com/ldez/exptostd v0.4.5 h1:kv2ZGUVI6VwRfp/+bcQ6Nbx0ghFWcGIKInkG/oFn1aQ= github.com/ldez/exptostd v0.4.5/go.mod h1:QRjHRMXJrCTIm9WxVNH6VW7oN7KrGSht69bIRwvdFsM= github.com/ldez/gomoddirectives v0.9.0 h1:2YV/EX7nVlWL4jySusYTzBKHuE3D2fgcRsQuMa3yIoo= @@ -747,8 +747,8 @@ github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSW github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= github.com/uudashr/gocognit v1.2.1 h1:CSJynt5txTnORn/DkhiB4mZjwPuifyASC8/6Q0I/QS4= github.com/uudashr/gocognit v1.2.1/go.mod h1:acaubQc6xYlXFEMb9nWX2dYBzJ/bIjEkc1zzvyIZg5Q= -github.com/uudashr/iface v1.5.0 h1:PgdMt4uAettGG8K/Kbamc4B9FABgUgnS3TLbl6fnjEk= -github.com/uudashr/iface v1.5.0/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg= +github.com/uudashr/iface v1.5.1 h1:BS3yrgaT55s3dAtJoxuTnsZNbsejq/mVuzp49YDyfBA= +github.com/uudashr/iface v1.5.1/go.mod h1:5UWoT6SvTdTww/KToRj6clO+n4Kg3/NrAQvgOB+5Ggw= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= @@ -937,11 +937,11 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= -honnef.co/go/tools v0.8.0 h1:UacpzPr7D6i5BAjTkA7sNVcx4kIbhAZcQ4zYtKiXx68= -honnef.co/go/tools v0.8.0/go.mod h1:XA+OnlRA9EDh/ukGvXMNSZNKGwFQJ+5dER0ioUkOxks= +honnef.co/go/tools v0.8.1 h1:+JKf3xJ1ni4CwrhVg4/pqsfPGP6vNAXcKbMXJodYx3w= +honnef.co/go/tools v0.8.1/go.mod h1:XA+OnlRA9EDh/ukGvXMNSZNKGwFQJ+5dER0ioUkOxks= mvdan.cc/gofumpt v0.11.0 h1:0H01XB95PnN2QgCSR9ELdZyTlJqNZ7181B0BTMh5VZc= mvdan.cc/gofumpt v0.11.0/go.mod h1:BeT5wCsOJt6J9zT2MZIOGszjUHzFkn1/l9g6xAzqsXo= -mvdan.cc/unparam v0.0.0-20260818115549-3f964bcb5673 h1:dEE6li4OPIE54oojY2qaayFS1fSp17G14si0gXRxl0U= -mvdan.cc/unparam v0.0.0-20260818115549-3f964bcb5673/go.mod h1:62roFV3D3nYOWIXv3PfGO4UYEKAotz2WgLywT87ONd8= +mvdan.cc/unparam v0.0.0-20260823230713-2fa3d841b0c8 h1:Re1NRyLpiAt9kB+ImaaoapwWiQXrKwER4tY8fLOkDew= +mvdan.cc/unparam v0.0.0-20260823230713-2fa3d841b0c8/go.mod h1:MrS/+zJ1M2xvGXhKktiHbNQeQPyg3Qel+KkzT+f7/i4= pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/vendor/github.com/lasiar/canonicalheader/.gitignore b/vendor/github.com/golangci/canonicalheader/.gitignore similarity index 100% rename from vendor/github.com/lasiar/canonicalheader/.gitignore rename to vendor/github.com/golangci/canonicalheader/.gitignore diff --git a/vendor/github.com/golangci/canonicalheader/.golangci.yaml b/vendor/github.com/golangci/canonicalheader/.golangci.yaml new file mode 100644 index 00000000..560daea8 --- /dev/null +++ b/vendor/github.com/golangci/canonicalheader/.golangci.yaml @@ -0,0 +1,425 @@ +version: "2" + +run: + build-tags: + - integration + modules-download-mode: readonly + +output: + formats: + text: + path: stdout + print-linter-name: true + print-issued-lines: false + colors: false + + +linters: + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - contextcheck + - copyloopvar + - dupword + - durationcheck + - errname + - errorlint + - gochecknoglobals + - gochecknoinits + - gocritic + - godot + - gomoddirectives + - gosec + - intrange + - mirror + - misspell + - nakedret + - nilerr + - nilnil + - noctx + - nolintlint + - perfsprint + - prealloc + - predeclared + - promlinter + - reassign + - revive + - rowserrcheck + - sloglint + - sqlclosecheck + - staticcheck + - tagliatelle + - testableexamples + - testifylint + - thelper + - tparallel + - unconvert + - unparam + - usestdlibvars + - wastedassign + disable: + - containedctx + - cyclop + - decorder + - depguard + - dogsled + - dupl + - err113 + - errchkjson + - exhaustive + - exhaustruct + - forbidigo + - forcetypeassert + - funlen + - ginkgolinter + - gocheckcompilerdirectives + - gocognit + - goconst + - gocyclo + - godox + - goheader + - gomodguard + - goprintffuncname + - grouper + - importas + - interfacebloat + - ireturn + - lll + - loggercheck + - maintidx + - makezero + - mnd + - musttag + - nestif + - nlreturn + - nonamedreturns + - nosprintfhostport + - paralleltest + - testpackage + - varnamelen + - whitespace + - wrapcheck + - wsl + + settings: + errcheck: + check-type-assertions: true + check-blank: true + exclude-functions: + - io/ioutil.ReadFile + - io.Copy(*bytes.Buffer) + - io.Copy(os.Stdout) + gocritic: + disabled-checks: + - hugeParam + - rangeExprCopy + - rangeValCopy + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + godot: + scope: all + govet: + disable: + - fieldalignment + nakedret: + max-func-lines: 1 + revive: + max-open-files: 2048 + confidence: 0.1 + severity: error + enable-all-rules: true + rules: + - name: add-constant + arguments: + - allowFloats: 0.0,0.,1.0,1.,2.0,2. + allowInts: 0,1,2 + allowStrs: '""' + maxLitCount: "3" + severity: warning + disabled: false + - name: argument-limit + arguments: + - 4 + severity: warning + disabled: false + - name: atomic + severity: warning + disabled: false + - name: banned-characters + severity: warning + disabled: false + - name: bare-return + severity: warning + disabled: false + - name: blank-imports + severity: warning + disabled: false + - name: bool-literal-in-expr + severity: warning + disabled: false + - name: call-to-gc + severity: warning + disabled: false + - name: cognitive-complexity + arguments: + - 7 + severity: warning + disabled: true + - name: comment-spacings + severity: warning + disabled: false + - name: confusing-naming + severity: warning + disabled: false + - name: confusing-results + severity: warning + disabled: false + - name: constant-logical-expr + severity: warning + disabled: false + - name: context-as-argument + severity: warning + disabled: false + - name: context-keys-type + severity: warning + disabled: false + - name: cyclomatic + arguments: + - 3 + severity: warning + disabled: true + - name: datarace + severity: warning + disabled: false + - name: deep-exit + severity: warning + disabled: true + - name: defer + severity: warning + disabled: false + - name: dot-imports + severity: warning + disabled: false + - name: duplicated-imports + severity: warning + disabled: false + - name: early-return + severity: warning + disabled: false + - name: empty-block + severity: warning + disabled: false + - name: empty-lines + severity: warning + disabled: false + - name: enforce-map-style + severity: warning + disabled: false + - name: error-naming + severity: warning + disabled: false + - name: error-return + severity: warning + disabled: false + - name: function-length + arguments: + - 10 + - 0 + severity: warning + disabled: true + - name: error-strings + severity: warning + disabled: false + - name: errorf + severity: warning + disabled: false + - name: exported + severity: warning + disabled: false + - name: file-header + severity: warning + disabled: true + - name: flag-parameter + severity: warning + disabled: false + - name: function-result-limit + arguments: + - 2 + severity: warning + disabled: false + - name: get-return + severity: warning + disabled: false + - name: identical-branches + severity: warning + disabled: false + - name: if-return + severity: warning + disabled: false + - name: increment-decrement + severity: warning + disabled: false + - name: indent-error-flow + severity: warning + disabled: false + - name: import-alias-naming + arguments: + - ^[a-z][a-z0-9]{0,}$ + severity: warning + disabled: false + - name: imports-blocklist + severity: warning + disabled: false + - name: import-shadowing + severity: warning + disabled: false + - name: line-length-limit + arguments: + - 80 + severity: warning + disabled: true + - name: max-public-structs + arguments: + - 3 + severity: warning + disabled: false + - name: modifies-parameter + severity: warning + disabled: false + - name: modifies-value-receiver + severity: warning + disabled: false + - name: nested-structs + severity: warning + disabled: false + - name: optimize-operands-order + severity: warning + disabled: false + - name: package-comments + severity: warning + disabled: false + - name: range + severity: warning + disabled: false + - name: range-val-in-closure + severity: warning + disabled: false + - name: range-val-address + severity: warning + disabled: false + - name: receiver-naming + severity: warning + disabled: false + - name: redundant-import-alias + severity: warning + disabled: false + - name: redefines-builtin-id + severity: warning + disabled: false + - name: string-of-int + severity: warning + disabled: false + - name: string-format + arguments: + - - core.WriteError[1].Message + - /^([^A-Z]|$)/ + - must not start with a capital letter + - - fmt.Errorf[0] + - /(^|[^\.!?])$/ + - must not end in punctuation + - - panic + - /^[^\n]*$/ + - must not contain line breaks + severity: warning + disabled: false + - name: struct-tag + arguments: + - json,inline + - bson,outline,gnu + severity: warning + disabled: false + - name: superfluous-else + severity: warning + disabled: false + - name: time-equal + severity: warning + disabled: false + - name: time-naming + severity: warning + disabled: false + - name: var-naming + severity: warning + disabled: false + - name: var-declaration + severity: warning + disabled: false + - name: unconditional-recursion + severity: warning + disabled: false + - name: unexported-naming + severity: warning + disabled: false + - name: unexported-return + severity: warning + disabled: false + - name: unhandled-error + severity: warning + disabled: false + - name: unnecessary-stmt + severity: warning + disabled: false + - name: unreachable-code + severity: warning + disabled: false + - name: unused-parameter + arguments: + - allowRegex: ^_ + severity: warning + disabled: false + - name: unused-receiver + severity: warning + disabled: false + - name: useless-break + severity: warning + disabled: false + - name: waitgroup-by-value + severity: warning + disabled: false + tagliatelle: + case: + rules: + avro: snake + bson: camel + json: snake + mapstructure: kebab + xml: camel + yaml: snake + exclusions: + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 + +formatters: + enable: + - gci + - gofmt + - gofumpt + - goimports + settings: + gci: + sections: + - standard + - default + - localmodule diff --git a/vendor/github.com/lasiar/canonicalheader/.goreleaser.yaml b/vendor/github.com/golangci/canonicalheader/.goreleaser.yaml similarity index 100% rename from vendor/github.com/lasiar/canonicalheader/.goreleaser.yaml rename to vendor/github.com/golangci/canonicalheader/.goreleaser.yaml diff --git a/vendor/github.com/lasiar/canonicalheader/LICENCE b/vendor/github.com/golangci/canonicalheader/LICENCE similarity index 100% rename from vendor/github.com/lasiar/canonicalheader/LICENCE rename to vendor/github.com/golangci/canonicalheader/LICENCE diff --git a/vendor/github.com/lasiar/canonicalheader/README.md b/vendor/github.com/golangci/canonicalheader/README.md similarity index 100% rename from vendor/github.com/lasiar/canonicalheader/README.md rename to vendor/github.com/golangci/canonicalheader/README.md diff --git a/vendor/github.com/lasiar/canonicalheader/analyzer.go b/vendor/github.com/golangci/canonicalheader/analyzer.go similarity index 74% rename from vendor/github.com/lasiar/canonicalheader/analyzer.go rename to vendor/github.com/golangci/canonicalheader/analyzer.go index 258ebdfd..4c0efaaa 100644 --- a/vendor/github.com/lasiar/canonicalheader/analyzer.go +++ b/vendor/github.com/golangci/canonicalheader/analyzer.go @@ -1,6 +1,7 @@ package canonicalheader import ( + "flag" "fmt" "go/ast" "go/types" @@ -18,12 +19,29 @@ const ( name = "Header" ) -//nolint:gochecknoglobals // struct is not big, can be skip. -var Analyzer = &analysis.Analyzer{ - Name: "canonicalheader", - Doc: "canonicalheader checks whether net/http.Header uses canonical header", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, +//nolint:gochecknoglobals // for backward compatibility. +var Analyzer = New() + +func New() *analysis.Analyzer { + c := &canonicalHeader{} + + a := &analysis.Analyzer{ + Name: "canonicalheader", + Doc: "canonicalheader checks whether net/http.Header uses canonical header", + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: c.run, + } + + a.Flags.Init("canonicalheader", flag.ExitOnError) + a.Flags.Var(&c.exclusions, "exclusions", "comma-separated list of exclusion rules") + a.Flags.BoolVar(&c.useDefaultExclusion, "useDefaultExclusion", true, "use default exclusion rules") + + return a +} + +type canonicalHeader struct { + useDefaultExclusion bool + exclusions stringSet } type argumenter interface { @@ -31,7 +49,26 @@ type argumenter interface { value() string } -func run(pass *analysis.Pass) (any, error) { +func (c *canonicalHeader) buildExclusions() map[string]string { + var defEx map[string]string + if c.useDefaultExclusion { + defEx = initialism() + } + + result := make(map[string]string, len(c.exclusions)+len(defEx)) + + for canonical, noCanonical := range defEx { + result[canonical] = noCanonical + } + + for _, ex := range c.exclusions { + result[http.CanonicalHeaderKey(ex)] = ex + } + + return result +} + +func (c *canonicalHeader) run(pass *analysis.Pass) (any, error) { var headerObject types.Object for _, object := range pass.TypesInfo.Uses { if object.Pkg() != nil && @@ -52,7 +89,7 @@ func run(pass *analysis.Pass) (any, error) { return nil, fmt.Errorf("want %T, got %T", spctor, pass.ResultOf[inspect.Analyzer]) } - wellKnownHeaders := initialism() + exclusions := c.buildExclusions() nodeFilter := []ast.Node{ (*ast.CallExpr)(nil), @@ -91,8 +128,15 @@ func run(pass *analysis.Pass) (any, error) { if recv == nil { return } + gotType = recv.Type() - gotMethodName = astcast.ToSelectorExpr(callExp.Fun).Sel.Name + + sel := astcast.ToSelectorExpr(callExp.Fun).Sel + if sel == nil { + return + } + + gotMethodName = sel.Name // h := http.Header{} // f := h.Get @@ -137,6 +181,10 @@ func run(pass *analysis.Pass) (any, error) { return } + if sel.Sel == nil { + return + } + gotMethodName = sel.Sel.Name ident, ok = sel.X.(*ast.Ident) if !ok { @@ -228,13 +276,9 @@ func run(pass *analysis.Pass) (any, error) { } argValue := arg.value() - headerKeyCanonical := http.CanonicalHeaderKey(argValue) - if argValue == headerKeyCanonical { - return - } - headerKeyCanonical, isWellKnown := canonicalHeaderKey(argValue, wellKnownHeaders) - if argValue == headerKeyCanonical || isWellKnown { + headerKeyCanonical := canonicalHeaderKey(argValue, exclusions) + if argValue == headerKeyCanonical { return } @@ -244,15 +288,15 @@ func run(pass *analysis.Pass) (any, error) { return nil, outerErr } -func canonicalHeaderKey(s string, m map[string]string) (string, bool) { +func canonicalHeaderKey(s string, m map[string]string) string { canonical := http.CanonicalHeaderKey(s) wellKnown, ok := m[canonical] if !ok { - return canonical, ok + return canonical } - return wellKnown, ok + return wellKnown } func isValidMethod(name string) bool { diff --git a/vendor/github.com/golangci/canonicalheader/configure.go b/vendor/github.com/golangci/canonicalheader/configure.go new file mode 100644 index 00000000..302a5a07 --- /dev/null +++ b/vendor/github.com/golangci/canonicalheader/configure.go @@ -0,0 +1,28 @@ +package canonicalheader + +import ( + "strings" +) + +// stringSet is a set-of-nonempty-strings-valued flag. +type stringSet []string + +func (s *stringSet) String() string { + return strings.Join(*s, ",") +} + +func (s *stringSet) Set(flag string) error { + list := strings.Split(flag, ",") + + *s = make(stringSet, 0, len(list)) + + for _, element := range list { + element = strings.TrimSpace(element) + if element == "" { + continue + } + + *s = append(*s, element) + } + return nil +} diff --git a/vendor/github.com/lasiar/canonicalheader/constant_string.go b/vendor/github.com/golangci/canonicalheader/constant_string.go similarity index 90% rename from vendor/github.com/lasiar/canonicalheader/constant_string.go rename to vendor/github.com/golangci/canonicalheader/constant_string.go index 27988f0d..9df31361 100644 --- a/vendor/github.com/lasiar/canonicalheader/constant_string.go +++ b/vendor/github.com/golangci/canonicalheader/constant_string.go @@ -37,10 +37,9 @@ func (c constantString) diagnostic(canonicalHeader string) analysis.Diagnostic { Pos: c.pos, End: c.end, Message: fmt.Sprintf( - "const %q used as a key at http.Header, but %q is not canonical, want %q", - c.nameOfConst, - c.originalValue, + "use %q instead of %q", canonicalHeader, + c.originalValue, ), } } diff --git a/vendor/github.com/lasiar/canonicalheader/initialism.go b/vendor/github.com/golangci/canonicalheader/initialism.go similarity index 100% rename from vendor/github.com/lasiar/canonicalheader/initialism.go rename to vendor/github.com/golangci/canonicalheader/initialism.go diff --git a/vendor/github.com/lasiar/canonicalheader/literal_string.go b/vendor/github.com/golangci/canonicalheader/literal_string.go similarity index 90% rename from vendor/github.com/lasiar/canonicalheader/literal_string.go rename to vendor/github.com/golangci/canonicalheader/literal_string.go index 71cd5f39..d1bd010f 100644 --- a/vendor/github.com/lasiar/canonicalheader/literal_string.go +++ b/vendor/github.com/golangci/canonicalheader/literal_string.go @@ -59,10 +59,10 @@ func (l literalString) diagnostic(canonicalHeader string) analysis.Diagnostic { return analysis.Diagnostic{ Pos: l.pos, End: l.end, - Message: fmt.Sprintf("non-canonical header %q, instead use: %q", l.originalValue, canonicalHeader), + Message: fmt.Sprintf("use %q instead of %q", canonicalHeader, l.originalValue), SuggestedFixes: []analysis.SuggestedFix{ { - Message: fmt.Sprintf("should replace %q with %q", l.originalValue, canonicalHeader), + Message: fmt.Sprintf("should be replaced %q with %q", l.originalValue, canonicalHeader), TextEdits: []analysis.TextEdit{ { Pos: l.pos, diff --git a/vendor/github.com/lasiar/canonicalheader/makefile b/vendor/github.com/golangci/canonicalheader/makefile similarity index 66% rename from vendor/github.com/lasiar/canonicalheader/makefile rename to vendor/github.com/golangci/canonicalheader/makefile index a96cb628..0f7a912a 100644 --- a/vendor/github.com/lasiar/canonicalheader/makefile +++ b/vendor/github.com/golangci/canonicalheader/makefile @@ -9,4 +9,5 @@ linter: generate: go run ./cmd/initialismer/*.go -target="mapping" > ./initialism.go go run ./cmd/initialismer/*.go -target="test" > ./testdata/src/initialism/initialism.go - gofmt -w ./initialism.go ./testdata/src/initialism/initialism.go + go run ./cmd/initialismer/*.go -target="test-golden" > ./testdata/src/initialism/initialism.go.golden + gofmt -w ./initialism.go ./testdata/src/initialism/initialism.go ./testdata/src/initialism/initialism.go.golden diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go index cf20b175..e681b6ee 100644 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go +++ b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go @@ -172,6 +172,10 @@ func (c *Cache) computePkgHash(pkg *packages.Package) (hashResults, error) { return nil, fmt.Errorf("failed to calculate file %s hash: %w", f, fErr) } + if rel, ok := toRelativePath(pkg.Module, f); ok { + f = pkg.Module.Path + "/" + rel + } + fmt.Fprintf(key, "file %s %x\n", f, h) } diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/cache/position.go b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/position.go new file mode 100644 index 00000000..88cf2b4a --- /dev/null +++ b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/position.go @@ -0,0 +1,54 @@ +package cache + +import ( + "go/token" + "path/filepath" + "strings" + + "golang.org/x/tools/go/packages" +) + +// RelativePosition creates a [token.Position] with a filename relative to the module directory. +func RelativePosition(mod *packages.Module, pos token.Position) token.Position { + pos.Filename, _ = toRelativePath(mod, pos.Filename) + + return pos +} + +// AbsolutionPosition creates the absolute path base on the module directory. +func AbsolutionPosition(mod *packages.Module, pos token.Position) token.Position { + pos.Filename = toAbsolutePath(mod, pos.Filename) + + return pos +} + +func toRelativePath(mod *packages.Module, filename string) (string, bool) { + if filename == "" || !isCurrentModule(mod) { + return filename, false + } + + rel, err := filepath.Rel(mod.Dir, filename) + if err != nil { + return filename, false + } + + rel = filepath.ToSlash(rel) + + if rel == ".." || strings.HasPrefix(rel, "../") { + return filename, false + } + + return rel, true +} + +func toAbsolutePath(mod *packages.Module, filename string) string { + if filename == "" || !isCurrentModule(mod) || filepath.IsAbs(filename) { + return filename + } + + return filepath.Join(mod.Dir, filepath.FromSlash(filename)) +} + +func isCurrentModule(mod *packages.Module) bool { + return mod != nil && mod.Dir != "" && mod.Version == "" +} diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.next.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.next.jsonschema.json index bb4f0398..0d8b5be5 100644 --- a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.next.jsonschema.json +++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.next.jsonschema.json @@ -1087,6 +1087,23 @@ } } }, + "canonicalheaderSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "use-default-exclusions": { + "type": "boolean", + "default": true + }, + "exclusions": { + "additionalProperties": false, + "type": "array", + "items": { + "type": "string" + } + } + } + }, "cyclopSettings": { "type": "object", "additionalProperties": false, @@ -5085,6 +5102,9 @@ "bodyclose": { "$ref": "#/definitions/settings/definitions/bodycloseSettings" }, + "canonicalheader": { + "$ref": "#/definitions/settings/definitions/canonicalheaderSettings" + }, "cyclop": { "$ref": "#/definitions/settings/definitions/cyclopSettings" }, diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go index a7efa264..58417f9d 100644 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go +++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go @@ -640,6 +640,7 @@ func initHashSalt(logger logutils.Log, version string, cfg *config.Config) error } b := bytes.NewBuffer(binSalt) + b.WriteString("golangci-lint-cache/v2") b.Write(configSalt) b.WriteString(goModSalt) @@ -712,7 +713,8 @@ func computeGoModSalt() (string, error) { return "", fmt.Errorf("failed to read go.mod: %w", err) } - sum, err := dirhash.Hash1([]string{goModPath}, func(string) (io.ReadCloser, error) { + // NOTE: the variable `goModPath` is not used here to ensure getting the same hash, independently of the location, for the same content. + sum, err := dirhash.Hash1([]string{"go.mod"}, func(string) (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(data)), nil }) if err != nil { diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go index e8561197..527c5f6f 100644 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go +++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go @@ -12,6 +12,9 @@ var defaultLintersSettings = LintersSettings{ Asasalint: AsasalintSettings{ UseBuiltinExclusions: true, }, + CanonicalHeader: CanonicalHeaderSettings{ + UseDefaultExclusions: true, + }, Decorder: DecorderSettings{ DecOrder: []string{"type", "const", "var", "func"}, DisableDecNumCheck: true, @@ -252,6 +255,7 @@ type LintersSettings struct { Asasalint AsasalintSettings `mapstructure:"asasalint"` BiDiChk BiDiChkSettings `mapstructure:"bidichk"` BodyClose BodyCloseSettings `mapstructure:"bodyclose"` + CanonicalHeader CanonicalHeaderSettings `mapstructure:"canonicalheader"` CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"` Cyclop CyclopSettings `mapstructure:"cyclop"` Decorder DecorderSettings `mapstructure:"decorder"` @@ -376,6 +380,11 @@ type BodyCloseSettings struct { CheckConsumption bool `mapstructure:"check-consumption"` } +type CanonicalHeaderSettings struct { + Exclusions []string `mapstructure:"exclusions"` + UseDefaultExclusions bool `mapstructure:"use-default-exclusions"` +} + type CopyLoopVarSettings struct { CheckAlias bool `mapstructure:"check-alias"` } diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go index b74d4f94..4e6ab9a1 100644 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go +++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go @@ -42,7 +42,7 @@ func saveIssuesToCache(allPkgs []*packages.Package, pkgsFromCache map[*packages. FromLinter: issue.FromLinter, Text: issue.Text, Severity: issue.Severity, - Pos: issue.Pos, + Pos: cache.RelativePosition(pkg.Module, issue.Pos), LineRange: issue.LineRange, SuggestedFixes: issue.SuggestedFixes, ExpectNoLint: issue.ExpectNoLint, @@ -114,7 +114,7 @@ func loadIssuesFromCache(pkgs []*packages.Package, lintCtx *linter.Context, FromLinter: issue.FromLinter, Text: issue.Text, Severity: issue.Severity, - Pos: issue.Pos, + Pos: cache.AbsolutionPosition(pkg.Module, issue.Pos), LineRange: issue.LineRange, SuggestedFixes: issue.SuggestedFixes, Pkg: pkg, diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go index 24e95f14..bbd6dbe4 100644 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go +++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go @@ -1,13 +1,29 @@ package canonicalheader import ( - "github.com/lasiar/canonicalheader" + "strings" + "github.com/golangci/canonicalheader" + + "github.com/golangci/golangci-lint/v2/pkg/config" "github.com/golangci/golangci-lint/v2/pkg/goanalysis" ) -func New() *goanalysis.Linter { +func New(settings *config.CanonicalHeaderSettings) *goanalysis.Linter { + var cfg map[string]any + + if settings != nil { + cfg = map[string]any{ + "useDefaultExclusion": settings.UseDefaultExclusions, + } + + if len(settings.Exclusions) > 0 { + cfg["exclusions"] = strings.Join(settings.Exclusions, ",") + } + } + return goanalysis. - NewLinterFromAnalyzer(canonicalheader.Analyzer). + NewLinterFromAnalyzer(canonicalheader.New()). + WithConfig(cfg). WithLoadMode(goanalysis.LoadModeTypesInfo) } diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go index d2b6ac04..fb70920a 100644 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go +++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go @@ -167,7 +167,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithLoadForGoAnalysis(). WithURL("https://github.com/timakin/bodyclose"), - linter.NewConfig(canonicalheader.New()). + linter.NewConfig(canonicalheader.New(&cfg.Linters.Settings.CanonicalHeader)). WithSince("v1.58.0"). WithLoadForGoAnalysis(). WithAutoFix(). diff --git a/vendor/github.com/lasiar/canonicalheader/.golangci.yaml b/vendor/github.com/lasiar/canonicalheader/.golangci.yaml deleted file mode 100644 index 997ec0cb..00000000 --- a/vendor/github.com/lasiar/canonicalheader/.golangci.yaml +++ /dev/null @@ -1,784 +0,0 @@ -# See: https://olegk.dev/go-linters-configuration-the-right-version - -run: - # Automatically adjust the maximum concurrency to the container CPU quota. - concurrency: 0 - - # I really care about the result, so I'm fine to wait for it. - timeout: 30m - - # Fail if the error was met. - issues-exit-code: 1 - - # This is very important, bugs in tests are not acceptable either. - tests: true - - # In most cases this can be empty but there is a popular pattern - # to keep integration tests under this tag. Such tests often require - # additional setups like Postgres, Redis etc and are run separately. - # (to be honest I don't find this useful but I have such tags) - build-tags: - - integration - - # Autogenerated files can be skipped (I'm looking at you gRPC). - # AFAIK autogen files are skipped but skipping the whole directory should be somewhat faster. - #skip-files: - # - "protobuf/.*.go" - - # With the read-only mode linter will fail if go.mod file is outdated. - modules-download-mode: readonly - - # Till today I didn't know this param exists, never ran 2 golangci-lint at once. - allow-parallel-runners: false - - # Keep this empty to use the Go version from the go.mod file. - go: "" - -linters: - # Set to true runs only fast linters. - # Good option for 'lint on save', pre-commit hook or CI. - fast: false - - enable: - # Globals and init() are no ok, because this linter use on golangci lint. - - gochecknoglobals - - gochecknoinits - # Check for pass []any as any in variadic func(...any). - # Rare case but saved me from debugging a few times. - - asasalint - - # I prefer plane ASCII identifiers. - # Symbol `∆` instead of `delta` looks cool but no thanks. - - asciicheck - - # Checks for dangerous unicode character sequences. - # Super rare but why not to be a bit paranoid? - - bidichk - - # Checks whether HTTP response body is closed successfully. - - bodyclose - - # Check whether the function uses a non-inherited context. - - contextcheck - - # after go 1.22 don't need copy var at for range. - - copyloopvar - - # Find duplicate words, rare. - - dupword - - # Check for two durations multiplied together. - - durationcheck - - # Forces to not skip error check. - - errcheck - - # Checks `Err-` prefix for var and `-Error` suffix for error type. - - errname - - # Suggests to use `%w` for error-wrapping. - - errorlint - - # Checks for pointers to enclosing loop variables. - - exportloopref - - - # Imports order. - - gci - - # As you already know I'm a co-author. It would be strange to not use - # one of my warmly loved projects. - - gocritic - - # Forces to put `.` at the end of the comment. Code is poetry. - - godot - - # Might not be that important but I prefer to keep all of them. - # `gofumpt` is amazing, kudos to Daniel Marti https://github.com/mvdan/gofumpt - - gofmt - - gofumpt - - goimports - - # Allow or ban replace directives in go.mod - # or force explanation for retract directives. - - gomoddirectives - - # Powerful security-oriented linter. But requires some time to - # configure it properly, see https://github.com/securego/gosec#available-rules - - gosec - - # Linter that specializes in simplifying code. - - gosimple - - # Official Go tool. Must have. - - govet - - # Detects when assignments to existing variables are not used - # Last week I caught a bug with it. - - ineffassign - - # range over int, work after go 1.22 - - intrange - - # Fix all the misspells, amazing thing. - - misspell - - # Reports wrong mirror patterns of bytes/strings usage. - - mirror - - # Finds naked/bare returns and requires change them. - - nakedret - - # Both require a bit more explicit returns. - - nilerr - - nilnil - - # Finds sending HTTP request without context.Context. - - noctx - - # Forces comment why another check is disabled. - # Better not to have //nolint: at all ;) - - nolintlint - - # aiming at usages of fmt.Sprintf which have faster alternatives. - - perfsprint - - # Finds slices that could potentially be pre-allocated. - # Small performance win + cleaner code. - - prealloc - - # Finds shadowing of Go's predeclared identifiers. - # I hear a lot of complaints from junior developers. - # But after some time they find it very useful. - - predeclared - - # Lint your Prometheus metrics name. - - promlinter - - # Checks that package variables are not reassigned. - # Super rare case but can catch bad things (like `io.EOF = nil`) - - reassign - - # Drop-in replacement of `golint`. - - revive - - # Somewhat similar to `bodyclose` but for `database/sql` package. - - rowserrcheck - - sqlclosecheck - - # Ensure consistent code style when using log/slog. - - sloglint - - # I have found that it's not the same as staticcheck binary :\ - - staticcheck - - # Is a replacement for `golint`, similar to `revive`. - - stylecheck - - # Check struct tags. - - tagliatelle - - # Test-related checks. All of them are good. - - tenv - - testableexamples - - testifylint - - thelper - - tparallel - - # Remove unnecessary type conversions, make code cleaner - - unconvert - - # Might be noisy but better to know what is unused - - unparam - - # Must have. Finds unused declarations. - - unused - - # Detect the possibility to use variables/constants from stdlib. - - usestdlibvars - - # Finds wasted assignment statements. - - wastedassign - - disable: - # Detects struct contained context.Context field. Not a problem. - - containedctx - - # Checks function and package cyclomatic complexity. - # I can have a long but trivial switch-case. - # - # Cyclomatic complexity is a measurement, not a goal. - # (c) Bryan C. Mills / https://github.com/bcmills - - cyclop - - # Check declaration order of types, consts, vars and funcs. - # I like it but I don't use it. - - decorder - - # Checks if package imports are in a list of acceptable packages. - # I'm very picky about what I import, so no automation. - - depguard - - # Checks assignments with too many blank identifiers. Very rare. - - dogsled - - # Tool for code clone detection. - - dupl - - # I'm fine to check the error from json.Marshal ¯\_(ツ)_/¯ - - errchkjson - - # All SQL queries MUST BE covered with tests. - - execinquery - - # Forces to handle more cases. Cool but noisy. - - exhaustive - - exhaustruct - - # Forbids some identifiers. I don't have a case for it. - - forbidigo - - # Finds forced type assertions, very good for juniors. - - forcetypeassert - - # I might have long but a simple function. - - funlen - - # I'm not a fan of ginkgo and gomega packages. - - ginkgolinter - - # Checks that compiler directive comments (//go:) are valid. Rare. - - gocheckcompilerdirectives - - # Same as `cyclop` linter (see above) - - gocognit - - goconst - - gocyclo - - # TODO and friends are ok. - - godox - - # Check the error handling expressions. Too noisy. - - err113 - - # I don't use file headers. - - goheader - - # Reports magic consts. Might be noisy but still good. - - mnd - - # Allowed/blocked packages to import. I prefer to do it manually. - - gomodguard - - # Printf-like functions must have -f. - - goprintffuncname - - # Groupt declarations, I prefer manually. - - grouper - - # Checks imports aliases, rare. - - importas - - # Forces tiny interfaces, very subjective. - - interfacebloat - - # Accept interfaces, return types. Not always. - - ireturn - - # I don't set line length. 120 is fine by the way ;) - - lll - - # Some log checkers, might be useful. - - loggercheck - - # Maintainability index of each function, subjective. - - maintidx - - # Slice declarations with non-zero initial length. Not my case. - - makezero - - # Enforce tags in un/marshaled structs. Cool but not my case. - - musttag - - # Deeply nested if statements, subjective. - - nestif - - # Forces newlines in some places. - - nlreturn - - # Reports all named returns, not that bad. - - nonamedreturns - - # Finds misuse of Sprintf with host:port in a URL. Cool but rare. - - nosprintfhostport - - # I don't use t.Parallel() that much. - - paralleltest - - # Often non-`_test` package is ok. - - testpackage - - # Compiler can do it too :) - - typecheck - - # I'm fine with long variable names with a small scope. - - varnamelen - - # gofmt,gofumpt covers that (from what I know). - - whitespace - - # Don't find it useful to wrap all errors from external packages. - - wrapcheck - - # Forces you to use empty lines. Great if configured correctly. - # I mean there is an agreement in a team. - - wsl - -linters-settings: - gci: - sections: - - standard - - default - - localmodule - - revive: - # Maximum number of open files at the same time. - # See https://github.com/mgechev/revive#command-line-flags - # Defaults to unlimited. - max-open-files: 2048 - # When set to false, ignores files with "GENERATED" header, similar to golint. - # See https://github.com/mgechev/revive#available-rules for details. - # Default: false - ignore-generated-header: true - # Sets the default severity. - # See https://github.com/mgechev/revive#configuration - # Default: warning - severity: error - # Enable all available rules. - # Default: false - enable-all-rules: true - # Sets the default failure confidence. - # This means that linting errors with less than 0.8 confidence will be ignored. - # Default: 0.8 - confidence: 0.1 - rules: - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#add-constant - - name: add-constant - severity: warning - disabled: false - arguments: - - maxLitCount: "3" - allowStrs: '""' - allowInts: "0,1,2" - allowFloats: "0.0,0.,1.0,1.,2.0,2." - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#argument-limit - - name: argument-limit - severity: warning - disabled: false - arguments: [4] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#atomic - - name: atomic - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#banned-characters - - name: banned-characters - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bare-return - - name: bare-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#blank-imports - - name: blank-imports - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr - - name: bool-literal-in-expr - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#call-to-gc - - name: call-to-gc - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cognitive-complexity - - name: cognitive-complexity - severity: warning - disabled: true - arguments: [7] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#comment-spacings - - name: comment-spacings - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-naming - - name: confusing-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-results - - name: confusing-results - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#constant-logical-expr - - name: constant-logical-expr - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument - - name: context-as-argument - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-keys-type - - name: context-keys-type - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cyclomatic - - name: cyclomatic - severity: warning - disabled: true - arguments: [3] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#datarace - - name: datarace - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#deep-exit - - name: deep-exit - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#defer - - name: defer - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#dot-imports - - name: dot-imports - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports - - name: duplicated-imports - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return - - name: early-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block - - name: empty-block - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines - - name: empty-lines - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-map-style - - name: enforce-map-style - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-naming - - name: error-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-return - - name: error-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-length - - name: function-length - severity: warning - disabled: true - arguments: [10, 0] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-strings - - name: error-strings - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#errorf - - name: errorf - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#exported - - name: exported - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#file-header - - name: file-header - severity: warning - disabled: true - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#flag-parameter - - name: flag-parameter - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-result-limit - - name: function-result-limit - severity: warning - disabled: false - arguments: [2] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#get-return - - name: get-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#identical-branches - - name: identical-branches - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#if-return - - name: if-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#increment-decrement - - name: increment-decrement - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow - - name: indent-error-flow - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-alias-naming - - name: import-alias-naming - severity: warning - disabled: false - arguments: - - "^[a-z][a-z0-9]{0,}$" - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#imports-blacklist - - name: imports-blacklist - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-shadowing - - name: import-shadowing - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#line-length-limit - - name: line-length-limit - severity: warning - disabled: true - arguments: [80] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#max-public-structs - - name: max-public-structs - severity: warning - disabled: false - arguments: [3] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-parameter - - name: modifies-parameter - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-value-receiver - - name: modifies-value-receiver - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#nested-structs - - name: nested-structs - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#optimize-operands-order - - name: optimize-operands-order - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments - - name: package-comments - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range - - name: range - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-in-closure - - name: range-val-in-closure - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-address - - name: range-val-address - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#receiver-naming - - name: receiver-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redundant-import-alias - - name: redundant-import-alias - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redefines-builtin-id - - name: redefines-builtin-id - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-of-int - - name: string-of-int - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-format - - name: string-format - severity: warning - disabled: false - arguments: - - - 'core.WriteError[1].Message' - - '/^([^A-Z]|$)/' - - must not start with a capital letter - - - 'fmt.Errorf[0]' - - '/(^|[^\.!?])$/' - - must not end in punctuation - - - panic - - '/^[^\n]*$/' - - must not contain line breaks - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#struct-tag - - name: struct-tag - arguments: - - "json,inline" - - "bson,outline,gnu" - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#superfluous-else - - name: superfluous-else - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-equal - - name: time-equal - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-naming - - name: time-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-naming - - name: var-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-declaration - - name: var-declaration - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unconditional-recursion - - name: unconditional-recursion - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-naming - - name: unexported-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-return - - name: unexported-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error - - name: unhandled-error - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unnecessary-stmt - - name: unnecessary-stmt - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unreachable-code - - name: unreachable-code - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter - - name: unused-parameter - severity: warning - disabled: false - arguments: - - allowRegex: "^_" - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-receiver - - name: unused-receiver - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break - - name: useless-break - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#waitgroup-by-value - - name: waitgroup-by-value - severity: warning - disabled: false - # I'm biased and I'm enabling more than 100 checks - # Might be too much for you. See https://go-critic.com/overview.html - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - # These 3 will detect many cases, but they do sense - # if it's performance oriented code - - hugeParam - - rangeExprCopy - - rangeValCopy - - godot: - scope: all - - errcheck: - # Report `a := b.(MyStruct)` when `a, ok := ...` should be. - check-type-assertions: true # Default: false - - # Report skipped checks:`num, _ := strconv.Atoi(numStr)`. - check-blank: true # Default: false - - # Function to skip. - exclude-functions: - - io/ioutil.ReadFile - - io.Copy(*bytes.Buffer) - - io.Copy(os.Stdout) - - govet: - disable: - - fieldalignment # I'm ok to waste some bytes - - nakedret: - # No naked returns, ever. - max-func-lines: 1 # Default: 30 - - tagliatelle: - case: - rules: - json: snake # why it's not a `snake` by default?! - yaml: snake # why it's not a `snake` by default?! - xml: camel - bson: camel - avro: snake - mapstructure: kebab - -# See also https://gist.github.com/cristaloleg/dc29ca0ef2fb554de28d94c3c6f6dc88 - -output: - # I prefer the simplest one: `line-number` and saving to `lint.txt` - # - # The `tab` also looks good and with the next release I will switch to it - # (ref: https://github.com/golangci/golangci-lint/issues/3728) - # - # There are more formats which can be used on CI or by your IDE. - formats: - - format: line-number - - # I do not find this useful, parameter above already enables filepath - # with a line and column. For me, it's easier to follow the path and - # see the line in an IDE where I see more code and understand it better. - print-issued-lines: false - - # Must have. Easier to understand the output. - print-linter-name: true - - # No, no skips, everything should be reported. - uniq-by-line: false - - # To be honest no idea when this can be needed, maybe a multi-module setup? - path-prefix: "" - - # Slightly easier to follow the results + getting deterministic output. - sort-results: true - -issues: - exclude-dirs-use-default: false - # I found it strange to skip the errors, setting 0 to have all the results. - max-issues-per-linter: 0 - - # Same here, nothing should be skipped to not miss errors. - max-same-issues: 0 - - # When set to `true` linter will analyze only new code which are - # not committed or after some specific revision. This is a cool - # feature when you're going to introduce linter into a big project. - # But I prefer going gradually package by package. - # So, it's set to `false` to scan all code. - new: false - - # 2 other params regarding git integration - - # Even with a recent GPT-4 release I still believe that - # I know better how to do my job and fix the suggestions. - fix: false \ No newline at end of file diff --git a/vendor/github.com/uudashr/iface/unexported/unexported.go b/vendor/github.com/uudashr/iface/unexported/unexported.go index c933d1b7..5e0c5c74 100644 --- a/vendor/github.com/uudashr/iface/unexported/unexported.go +++ b/vendor/github.com/uudashr/iface/unexported/unexported.go @@ -5,7 +5,6 @@ import ( "go/ast" "go/types" "os" - "strings" "github.com/uudashr/iface/internal/directive" "golang.org/x/tools/go/analysis" @@ -55,19 +54,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { var recvName string if recv := funcDecl.Recv; recv != nil { - recvType := recv.List[0].Type - - if r.debug { - infoType := pass.TypesInfo.TypeOf(recvType) - fmt.Fprintf(os.Stderr, " recvType: %v infoType: %v reflectType: %T\n", recvType, infoType, recvType) - } - - inner := recvType - if star, ok := inner.(*ast.StarExpr); ok { - inner = star.X - } - - recvName = typeName(inner) + recvName = r.recvName(pass, recv.List[0].Type) } if !funcDecl.Name.IsExported() { @@ -121,62 +108,36 @@ func findIdent(expr ast.Expr) ast.Expr { case *ast.Ident, *ast.SelectorExpr: return e default: + // should not happen return nil } } } -// typeName reconstructs the type string as written in source from an AST expression. -func typeName(expr ast.Expr) string { - switch e := expr.(type) { - case *ast.ArrayType: - if e.Len == nil { - return "[]" + typeName(e.Elt) +func formatType(pass *analysis.Pass, expr ast.Expr, infoType types.Type) string { + qualifier := func(p *types.Package) string { + if p == pass.Pkg { + return "" } - return "[" + typeName(e.Len) + "]" + typeName(e.Elt) - case *ast.BasicLit: - return e.Value - case *ast.Ident: - return e.Name - case *ast.StarExpr: - return "*" + typeName(e.X) - case *ast.Ellipsis: - return "..." + typeName(e.Elt) - case *ast.ChanType: - switch e.Dir { - case ast.SEND: - return "chan<- " + typeName(e.Value) - case ast.RECV: - return "<-chan " + typeName(e.Value) - default: - return "chan " + typeName(e.Value) - } - case *ast.MapType: - return "map[" + typeName(e.Key) + "]" + typeName(e.Value) - case *ast.SelectorExpr: - return typeName(e.X) + "." + e.Sel.Name - case *ast.IndexExpr: - return typeName(e.X) + "[" + typeName(e.Index) + "]" - case *ast.IndexListExpr: - var b strings.Builder - b.WriteString(typeName(e.X)) - b.WriteByte('[') - - for i, idx := range e.Indices { - if i > 0 { - b.WriteString(", ") - } - - b.WriteString(typeName(idx)) - } + return p.Name() + } - b.WriteByte(']') + if ellipsis, ok := expr.(*ast.Ellipsis); ok { + elemType := pass.TypesInfo.TypeOf(ellipsis.Elt) - return b.String() - default: - return fmt.Sprintf("%T", expr) + return "..." + types.TypeString(elemType, qualifier) } + + return types.TypeString(infoType, qualifier) +} + +func funcKindName(funcDecl *ast.FuncDecl, recvName string) (kind, name string) { + if recvName != "" { + return "method", recvName + "." + funcDecl.Name.Name + } + + return "function", funcDecl.Name.Name } func (r *runner) checkType(pass *analysis.Pass, expr ast.Expr, funcDecl *ast.FuncDecl, recvName, role string) { @@ -230,20 +191,30 @@ func (r *runner) checkType(pass *analysis.Pass, expr ast.Expr, funcDecl *ast.Fun r.debugln(" unexported") - funcMethod := "function" - funcMethodName := funcDecl.Name.Name - - if recvName != "" { - funcMethod = "method" - funcMethodName = recvName + "." + funcDecl.Name.Name - } + kind, name := funcKindName(funcDecl, recvName) + typeStr := formatType(pass, expr, infoType) pass.Report(analysis.Diagnostic{ Pos: typ.Pos(), - Message: fmt.Sprintf("unexported interface '%s' used as %s in exported %s '%s'", typeName(expr), role, funcMethod, funcMethodName), + Message: fmt.Sprintf("unexported interface '%s' used as %s in exported %s '%s'", typeStr, role, kind, name), }) } +func (r *runner) recvName(pass *analysis.Pass, recvType ast.Expr) string { + inner := recvType + + if star, ok := inner.(*ast.StarExpr); ok { + inner = star.X + } + + infoType := pass.TypesInfo.TypeOf(inner) + if infoType == nil { + return "" + } + + return formatType(pass, inner, infoType) +} + func (r *runner) debugln(a ...any) { if r.debug { fmt.Fprintln(os.Stderr, a...) diff --git a/vendor/github.com/uudashr/iface/unused/unused.go b/vendor/github.com/uudashr/iface/unused/unused.go index 743e2942..a6ffb057 100644 --- a/vendor/github.com/uudashr/iface/unused/unused.go +++ b/vendor/github.com/uudashr/iface/unused/unused.go @@ -4,6 +4,7 @@ import ( "fmt" "go/ast" "go/token" + "go/types" "os" "slices" "strings" @@ -35,8 +36,9 @@ func newAnalyzer() *analysis.Analyzer { } type ifaceEntry struct { - ts *ast.TypeSpec - decl *ast.GenDecl + ifaceName string + ts *ast.TypeSpec + decl *ast.GenDecl } type runner struct { @@ -62,7 +64,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) // Collect all interface type declarations - ifaces := make(map[string]ifaceEntry) + ifaces := make(map[*types.TypeName]ifaceEntry) nodeFilter := []ast.Node{ (*ast.GenDecl)(nil), @@ -105,14 +107,25 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { continue } - ifaces[ts.Name.Name] = ifaceEntry{ts: ts, decl: decl} + obj := pass.TypesInfo.Defs[ts.Name] + + typeName, ok := obj.(*types.TypeName) + if !ok { + continue + } + + ifaces[typeName] = ifaceEntry{ + ifaceName: ts.Name.Name, + ts: ts, + decl: decl, + } } }) if r.debug { var ifaceNames []string - for name := range ifaces { - ifaceNames = append(ifaceNames, name) + for tn := range ifaces { + ifaceNames = append(ifaceNames, tn.Name()) } fmt.Fprintln(os.Stderr, "Declared interfaces:", ifaceNames) @@ -129,23 +142,28 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { return } - entry, ok := ifaces[ident.Name] + obj := pass.TypesInfo.Uses[ident] + + typeName, ok := obj.(*types.TypeName) if !ok { return } - if entry.ts.Pos() == ident.Pos() { + entry, ok := ifaces[typeName] + if !ok { return } - delete(ifaces, ident.Name) + r.debugln(" used:", entry.ifaceName) + + delete(ifaces, typeName) }) if r.debug { fmt.Fprintf(os.Stderr, "Package %s %s\n", pass.Pkg.Path(), pass.Pkg.Name()) } - for name, entry := range ifaces { + for typeName, entry := range ifaces { ts := entry.ts decl := entry.decl @@ -166,7 +184,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) { end = ts.End() } - msg := fmt.Sprintf("interface '%s' is declared but not used within the package", name) + msg := fmt.Sprintf("interface '%s' is declared but not used within the package", typeName.Name()) pass.Report(analysis.Diagnostic{ Pos: ts.Pos(), Message: msg, diff --git a/vendor/github.com/uudashr/iface/unusedmethod/doc.go b/vendor/github.com/uudashr/iface/unusedmethod/doc.go index cef63a7f..af353eb2 100644 --- a/vendor/github.com/uudashr/iface/unusedmethod/doc.go +++ b/vendor/github.com/uudashr/iface/unusedmethod/doc.go @@ -1,3 +1,8 @@ // Package unusedmethod defines an Analyzer that detects interface methods which // are never used anywhere in the same package where they are defined. +// +// A method is considered used only when it is invoked or referenced through a +// value of the interface type. Merely implementing the interface — for example, +// assigning a concrete type to the interface, or calling the method directly on +// the concrete type — does not count as a use. package unusedmethod diff --git a/vendor/github.com/uudashr/iface/unusedmethod/unusedmethod.go b/vendor/github.com/uudashr/iface/unusedmethod/unusedmethod.go index 2f671465..240ac972 100644 --- a/vendor/github.com/uudashr/iface/unusedmethod/unusedmethod.go +++ b/vendor/github.com/uudashr/iface/unusedmethod/unusedmethod.go @@ -22,7 +22,7 @@ func newAnalyzer() *analysis.Analyzer { analyzer := &analysis.Analyzer{ Name: "unusedmethod", - Doc: "Detects interface methods that are never used anywhere in the same package where they are defined.", + Doc: "Detects interface methods that are never used anywhere in the same package where they are defined. A method is considered used only when invoked or referenced through a value of the interface type; merely implementing the interface does not count as a use.", URL: "https://pkg.go.dev/github.com/uudashr/iface/unusedmethod", Requires: []*analysis.Analyzer{inspect.Analyzer}, Run: r.run, diff --git a/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go b/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go index 25b315bc..14198f81 100644 --- a/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go +++ b/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go @@ -67,7 +67,7 @@ var Analysis = &analysis.Analyzer{ // Nilness returns nilness information for return value ret of fn. func (r *Result) Nilness(fn *types.Func, ret int) ValueNilness { typ := fn.Type().(*types.Signature).Results().At(ret).Type() - if !typeutil.IsPointerLike(typ) { + if !typeutil.MaybePointerLike(typ) { return ValueNilness{Outer: NeverNil} } if len(r.m[fn]) == 0 { @@ -145,7 +145,7 @@ type state struct { } func (s *state) get(v ir.Value) ValueNilness { - if !typeutil.IsPointerLike(v.Type()) { + if !typeutil.MaybePointerLike(v.Type()) { // All non-pointer-like types are always {_ NeverNil}. return ValueNilness{Outer: NeverNil} } @@ -173,7 +173,7 @@ func (s *state) get(v ir.Value) ValueNilness { } func (s *state) set(key ir.Value, value ValueNilness) { - if !typeutil.IsPointerLike(key.Type()) { + if !typeutil.MaybePointerLike(key.Type()) { // No point in recording state for non-pointer-like types. They're // always {_ NeverNil}. return @@ -199,7 +199,7 @@ func (s *state) set(key ir.Value, value ValueNilness) { } func (s *state) setInner(key ir.Value, value Nilness) { - if !typeutil.IsPointerLike(key.Type()) { + if !typeutil.MaybePointerLike(key.Type()) { return } if value == (lattice{}.Ident().Inner) { @@ -225,7 +225,7 @@ func (s *state) setInner(key ir.Value, value Nilness) { } func (s *state) setOuter(key ir.Value, value Nilness) { - if !typeutil.IsPointerLike(key.Type()) { + if !typeutil.MaybePointerLike(key.Type()) { return } if value == (lattice{}).Ident().Outer { @@ -263,7 +263,7 @@ func defaultNilnessForSignature(pass *analysis.Pass, typ *types.Signature) []Val } func defaultNilness(pass *analysis.Pass, typ types.Type) ValueNilness { - if typeutil.IsPointerLike(typ) { + if typeutil.MaybePointerLike(typ) { // IsPointerLike handles type parameters with type sets, too. return ValueNilness{MaybeNil, MaybeNil} } else { @@ -302,7 +302,7 @@ start: anyPointers := false for ret := range fn.Signature.Results().Variables() { - if typeutil.IsPointerLike(ret.Type()) { + if typeutil.MaybePointerLike(ret.Type()) { anyPointers = true break } @@ -317,7 +317,7 @@ start: processBlock := func(from, to *ir.BasicBlock, s state) state { handleReturnValue := func(v ir.Value, call *ir.Call, idx int) { typ := call.Common().Signature().Results().At(idx).Type() - if !typeutil.IsPointerLike(typ) { + if !typeutil.MaybePointerLike(typ) { s.setOuter(v, NeverNil) return } @@ -683,7 +683,7 @@ start: // defaults. entrys := state{cloned: true, n: n} for _, param := range fn.Params { - if typeutil.IsPointerLike(param.Type()) { + if typeutil.MaybePointerLike(param.Type()) { entrys.set(param, ValueNilness{Inner: MaybeNil, Outer: MaybeNil}) } else { // We never track nilness for value types, so they don't have to be @@ -707,7 +707,7 @@ start: for _, instr := range b.Instrs { ops = instr.Operands(ops[:0]) for _, pop := range ops { - if op, ok := (*pop).(*ir.Const); ok && typeutil.IsPointerLike(op.Type()) { + if op, ok := (*pop).(*ir.Const); ok && typeutil.MaybePointerLike(op.Type()) { // The only constant pointer-like is nil. entrys.set(op, ValueNilness{Inner: AlwaysNil, Outer: AlwaysNil}) } @@ -741,7 +741,7 @@ start: interesting := false for i := range retNilness { typ := fn.Signature.Results().At(i).Type() - if !typeutil.IsPointerLike(typ) { + if !typeutil.MaybePointerLike(typ) { retNilness[i] = ValueNilness{NeverNil, NeverNil} continue } diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/util.go b/vendor/honnef.co/go/tools/go/types/typeutil/util.go index bb506622..ffbd4837 100644 --- a/vendor/honnef.co/go/tools/go/types/typeutil/util.go +++ b/vendor/honnef.co/go/tools/go/types/typeutil/util.go @@ -144,9 +144,10 @@ func IsTypeWithName(typ types.Type, name string) bool { } } -// IsPointerLike returns true if type T is like a pointer. This returns true for all nillable types, -// unsafe.Pointer, and type sets where at least one term is pointer-like. -func IsPointerLike(T types.Type) bool { +// MaybePointerLike returns true if type T is like a pointer. This returns true +// for all nillable types, unsafe.Pointer, type sets where at least one term is +// pointer-like, and type sets without structural restrictions.. +func MaybePointerLike(T types.Type) bool { switch T := T.Underlying().(type) { case *types.Interface: if T.IsMethodSet() { @@ -157,11 +158,11 @@ func IsPointerLike(T types.Type) bool { return false } for _, term := range terms { - if IsPointerLike(term.Type()) { + if MaybePointerLike(term.Type()) { return true } } - return false + return len(terms) == 0 } case *types.Chan, *types.Map, *types.Signature, *types.Pointer, *types.Slice: return true diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go b/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go index 3f1e866f..67ca67c6 100644 --- a/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go +++ b/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go @@ -179,7 +179,15 @@ func run(pass *analysis.Pass) (any, error) { } nillity := nilnessRes.Nilness(obj, idx) + // We aim to detect interface values that are never nil (i.e., + // always typed) but may contain typed nils. This usually + // points to a bug in the producer of the value. We + // intentionally do not flag comparisons with non-nil interface + // values whose stored value is also never nil (such as the + // return value of errors.New)--those are more likely to be + // defensive code, protecting against a future untyped nil. if nillity.Outer == nilness.NeverNil && + (nillity.Inner == nilness.MaybeNil || nillity.Inner == nilness.AlwaysNil) && !code.IsInTest(pass, binop) && !irutil.IsTrivial(irpkg.Pkg.Prog.FuncValue(obj)) { // Don't flag these comparisons in tests. Tests may be diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go b/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go index 7eaa095c..f0ab7ecc 100644 --- a/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go +++ b/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go @@ -252,7 +252,7 @@ func checkImpl(carg *callcheck.Argument, f ir.Value, args []ir.Value) { } } - if flags&isPointer != 0 && typeutil.IsPointerLike(T) { + if flags&isPointer != 0 && typeutil.MaybePointerLike(T) { return true } if flags&isPseudoPointer != 0 { diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go b/vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go index 91ec7303..edfe60a3 100644 --- a/vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go +++ b/vendor/honnef.co/go/tools/staticcheck/sa6002/sa6002.go @@ -45,7 +45,7 @@ var rules = map[string]callcheck.Check{ arg := call.Args[knowledge.Arg("(*sync.Pool).Put.x")] typ := arg.Value.Value.Type() _, isSlice := typ.Underlying().(*types.Slice) - if !typeutil.IsPointerLike(typ) || isSlice { + if !typeutil.MaybePointerLike(typ) || isSlice { arg.Invalid("argument should be pointer-like to avoid allocations") } }, diff --git a/vendor/modules.txt b/vendor/modules.txt index 98df1032..d3102d56 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -639,6 +639,9 @@ github.com/golang-jwt/jwt/v4 # github.com/golangci/asciicheck v0.5.0 ## explicit; go 1.23.0 github.com/golangci/asciicheck +# github.com/golangci/canonicalheader v0.0.0-20260827115959-a25c71c521f6 +## explicit; go 1.25.0 +github.com/golangci/canonicalheader # github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 ## explicit; go 1.22.0 github.com/golangci/dupl/job @@ -654,7 +657,7 @@ github.com/golangci/go-printf-func-name/pkg/analyzer ## explicit; go 1.26.0 github.com/golangci/gofmt github.com/golangci/gofmt/internal -# github.com/golangci/golangci-lint/v2 v2.13.1 +# github.com/golangci/golangci-lint/v2 v2.13.2 ## explicit; go 1.26.0 github.com/golangci/golangci-lint/v2/cmd/golangci-lint github.com/golangci/golangci-lint/v2/internal/cache @@ -980,9 +983,6 @@ github.com/kulti/thelper/pkg/analyzer # github.com/kunwardeep/paralleltest v1.0.15 ## explicit; go 1.23.0 github.com/kunwardeep/paralleltest/pkg/paralleltest -# github.com/lasiar/canonicalheader v1.1.2 -## explicit; go 1.22.0 -github.com/lasiar/canonicalheader # github.com/ldez/exptostd v0.4.5 ## explicit; go 1.24.0 github.com/ldez/exptostd @@ -1458,8 +1458,8 @@ github.com/ultraware/whitespace # github.com/uudashr/gocognit v1.2.1 ## explicit; go 1.24.0 github.com/uudashr/gocognit -# github.com/uudashr/iface v1.5.0 -## explicit; go 1.23.0 +# github.com/uudashr/iface v1.5.1 +## explicit; go 1.25.0 github.com/uudashr/iface/identical github.com/uudashr/iface/internal/directive github.com/uudashr/iface/opaque @@ -1780,7 +1780,7 @@ gopkg.in/ini.v1 # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 -# honnef.co/go/tools v0.8.0 +# honnef.co/go/tools v0.8.1 ## explicit; go 1.26.0 honnef.co/go/tools/analysis/callcheck honnef.co/go/tools/analysis/code @@ -1990,6 +1990,6 @@ mvdan.cc/gofumpt/internal/govendor/go/doc/comment mvdan.cc/gofumpt/internal/govendor/go/format mvdan.cc/gofumpt/internal/govendor/go/printer mvdan.cc/gofumpt/internal/version -# mvdan.cc/unparam v0.0.0-20260818115549-3f964bcb5673 -## explicit; go 1.25.0 +# mvdan.cc/unparam v0.0.0-20260823230713-2fa3d841b0c8 +## explicit; go 1.26.0 mvdan.cc/unparam/check diff --git a/vendor/mvdan.cc/unparam/check/check.go b/vendor/mvdan.cc/unparam/check/check.go index 6bd6fdb6..8015b78a 100644 --- a/vendor/mvdan.cc/unparam/check/check.go +++ b/vendor/mvdan.cc/unparam/check/check.go @@ -650,8 +650,6 @@ resLoop: c.addIssue(fn, res.Pos(), "result %s is never used", name) } - fnIsGeneric := fn.TypeParams().Len() > 0 - for i, par := range fn.Params { if paramsBy != "" { continue // we can't change the params @@ -666,13 +664,9 @@ resLoop: } t := par.Type() // asking for the size of a type param would panic, as it is unknowable - if !fnIsGeneric || !containsTypeParam(t) { - if stdSizes.Sizeof(par.Type()) == 0 { - c.debug(" skip - zero size\n") - continue - } - } else { - c.debug(" examine - type parameter\n") + if !containsTypeParam(t) && stdSizes.Sizeof(t) == 0 { + c.debug(" skip - zero size\n") + continue } reason := "is unused" constStr := c.alwaysReceivedConst(callSites, par, i) @@ -686,6 +680,9 @@ resLoop: } } +// containsTypeParam reports whether computing the size of t requires knowing +// the size of a type parameter. It only follows the types that [types.Sizes] +// descends into; the rest have a fixed size. func containsTypeParam(t types.Type) bool { switch t := types.Unalias(t).(type) { case *types.TypeParam, *types.Union: @@ -700,12 +697,7 @@ func containsTypeParam(t types.Type) bool { case *types.Array: return containsTypeParam(t.Elem()) case *types.Named: - args := t.TypeArgs() - for t0 := range args.Types() { - if containsTypeParam(t0) { - return true - } - } + return containsTypeParam(t.Underlying()) } return false }