diff options
| author | Taras Madan <tarasmadan@google.com> | 2023-07-20 10:46:22 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2023-07-20 12:32:54 +0000 |
| commit | 1b601bfed3244691624357968d5d018b50bffc5a (patch) | |
| tree | 2b7ff934678209301df15f54f56e942284837108 /vendor/github.com/polyfloyd | |
| parent | 75ccff38aa5f5663fd1280a4a78cc0e34212e4db (diff) | |
go.mod: update golangci-lint to 1.53.3
Diffstat (limited to 'vendor/github.com/polyfloyd')
4 files changed, 105 insertions, 76 deletions
diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go index c9dcf5e55..366b5c6b0 100644 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go +++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go @@ -10,8 +10,8 @@ var allowedErrors = []struct { fun string }{ // pkg/archive/tar - {err: "io.EOF", fun: "(*tar.Reader).Next"}, - {err: "io.EOF", fun: "(*tar.Reader).Read"}, + {err: "io.EOF", fun: "(*archive/tar.Reader).Next"}, + {err: "io.EOF", fun: "(*archive/tar.Reader).Read"}, // pkg/bufio {err: "io.EOF", fun: "(*bufio.Reader).Discard"}, {err: "io.EOF", fun: "(*bufio.Reader).Peek"}, @@ -154,10 +154,10 @@ func assigningCallExprs(info *TypesInfoExt, subject *ast.Ident) []*ast.CallExpr assigningExpr := assignment.Rhs[0] // If the assignment is comprised of multiple expressions, find out - // which LHS expression we should use by finding its index in the LHS. - if len(assignment.Rhs) > 1 { + // which RHS expression we should use by finding its index in the LHS. + if len(assignment.Lhs) == len(assignment.Rhs) { for i, lhs := range assignment.Lhs { - if subject.Name == lhs.(*ast.Ident).Name { + if ident, ok := lhs.(*ast.Ident); ok && subject.Name == ident.Name { assigningExpr = assignment.Rhs[i] break } diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go index ab02136f4..c65c4ee62 100644 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go +++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go @@ -19,20 +19,22 @@ func NewAnalyzer() *analysis.Analyzer { } var ( - flagSet flag.FlagSet - checkComparison bool - checkAsserts bool - checkErrorf bool + flagSet flag.FlagSet + checkComparison bool + checkAsserts bool + checkErrorf bool + checkErrorfMulti bool ) func init() { flagSet.BoolVar(&checkComparison, "comparison", true, "Check for plain error comparisons") flagSet.BoolVar(&checkAsserts, "asserts", true, "Check for plain type assertions and type switches") flagSet.BoolVar(&checkErrorf, "errorf", false, "Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats") + flagSet.BoolVar(&checkErrorfMulti, "errorf-multi", true, "Permit more than 1 %w verb, valid per Go 1.20 (Requires -errorf=true)") } func run(pass *analysis.Pass) (interface{}, error) { - lints := []Lint{} + lints := []analysis.Diagnostic{} extInfo := newTypesInfoExt(pass.TypesInfo) if checkComparison { l := LintErrorComparisons(pass.Fset, extInfo) @@ -43,13 +45,13 @@ func run(pass *analysis.Pass) (interface{}, error) { lints = append(lints, l...) } if checkErrorf { - l := LintFmtErrorfCalls(pass.Fset, *pass.TypesInfo) + l := LintFmtErrorfCalls(pass.Fset, *pass.TypesInfo, checkErrorfMulti) lints = append(lints, l...) } sort.Sort(ByPosition(lints)) for _, l := range lints { - pass.Report(analysis.Diagnostic{Pos: l.Pos, Message: l.Message}) + pass.Report(l) } return nil, nil } diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go index b9ebe6efe..920dc56e7 100644 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go +++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go @@ -6,14 +6,11 @@ import ( "go/constant" "go/token" "go/types" -) -type Lint struct { - Message string - Pos token.Pos -} + "golang.org/x/tools/go/analysis" +) -type ByPosition []Lint +type ByPosition []analysis.Diagnostic func (l ByPosition) Len() int { return len(l) } func (l ByPosition) Swap(i, j int) { l[i], l[j] = l[j], l[i] } @@ -22,8 +19,8 @@ func (l ByPosition) Less(i, j int) bool { return l[i].Pos < l[j].Pos } -func LintFmtErrorfCalls(fset *token.FileSet, info types.Info) []Lint { - lints := []Lint{} +func LintFmtErrorfCalls(fset *token.FileSet, info types.Info, multipleWraps bool) []analysis.Diagnostic { + lints := []analysis.Diagnostic{} for expr, t := range info.Types { // Search for error expressions that are the result of fmt.Errorf // invocations. @@ -42,52 +39,87 @@ func LintFmtErrorfCalls(fset *token.FileSet, info types.Info) []Lint { } // For any arguments that are errors, check whether the wrapping verb is used. %w may occur - // for multiple errors in one Errorf invocation. We raise an issue if at least one error - // does not have a corresponding wrapping verb. - var lintArg ast.Expr + // for multiple errors in one Errorf invocation, unless multipleWraps is true. We raise an + // issue if at least one error does not have a corresponding wrapping verb. args := call.Args[1:] - for i := 0; i < len(args) && i < len(formatVerbs); i++ { - if !implementsError(info.Types[args[i]].Type) && !isErrorStringCall(info, args[i]) { - continue - } + if !multipleWraps { + wrapCount := 0 + for i := 0; i < len(args) && i < len(formatVerbs); i++ { + arg := args[i] + if !implementsError(info.Types[arg].Type) { + continue + } + verb := formatVerbs[i] + + if verb.format == "w" { + wrapCount++ + if wrapCount > 1 { + lints = append(lints, analysis.Diagnostic{ + Message: "only one %w verb is permitted per format string", + Pos: arg.Pos(), + }) + break + } + } - if formatVerbs[i] == "w" { - continue + if wrapCount == 0 { + lints = append(lints, analysis.Diagnostic{ + Message: "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors", + Pos: args[i].Pos(), + }) + break + } } - if lintArg == nil { - lintArg = args[i] - break - } - } - if lintArg != nil { - lints = append(lints, Lint{ - Message: "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors", - Pos: lintArg.Pos(), - }) - } - } - return lints -} + } else { + var lint *analysis.Diagnostic + argIndex := 0 + for _, verb := range formatVerbs { + if verb.index != -1 { + argIndex = verb.index + } else { + argIndex++ + } + + if verb.format == "w" { + continue + } + if argIndex-1 >= len(args) { + continue + } + arg := args[argIndex-1] + if !implementsError(info.Types[arg].Type) { + continue + } -// isErrorStringCall tests whether the expression is a string expression that -// is the result of an `(error).Error()` method call. -func isErrorStringCall(info types.Info, expr ast.Expr) bool { - if info.Types[expr].Type.String() == "string" { - if call, ok := expr.(*ast.CallExpr); ok { - if callSel, ok := call.Fun.(*ast.SelectorExpr); ok { - fun := info.Uses[callSel.Sel].(*types.Func) - return fun.Type().String() == "func() string" && fun.Name() == "Error" + strStart := call.Args[0].Pos() + if lint == nil { + lint = &analysis.Diagnostic{ + Message: "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors", + Pos: arg.Pos(), + } + } + lint.SuggestedFixes = append(lint.SuggestedFixes, analysis.SuggestedFix{ + Message: "Use `%w` to format errors", + TextEdits: []analysis.TextEdit{{ + Pos: strStart + token.Pos(verb.formatOffset) + 1, + End: strStart + token.Pos(verb.formatOffset) + 2, + NewText: []byte("w"), + }}, + }) + } + if lint != nil { + lints = append(lints, *lint) } } } - return false + return lints } // printfFormatStringVerbs returns a normalized list of all the verbs that are used per argument to // the printf function. The index of each returned element corresponds to the index of the // respective argument. -func printfFormatStringVerbs(info types.Info, call *ast.CallExpr) ([]string, bool) { +func printfFormatStringVerbs(info types.Info, call *ast.CallExpr) ([]verb, bool) { if len(call.Args) <= 1 { return nil, false } @@ -103,18 +135,8 @@ func printfFormatStringVerbs(info types.Info, call *ast.CallExpr) ([]string, boo if err != nil { return nil, false } - orderedVerbs := verbOrder(verbs, len(call.Args)-1) - - resolvedVerbs := make([]string, len(orderedVerbs)) - for i, vv := range orderedVerbs { - for _, v := range vv { - resolvedVerbs[i] = v.format - if v.format == "w" { - break - } - } - } - return resolvedVerbs, true + + return verbs, true } func isFmtErrorfCallExpr(info types.Info, expr ast.Expr) (*ast.CallExpr, bool) { @@ -136,8 +158,8 @@ func isFmtErrorfCallExpr(info types.Info, expr ast.Expr) (*ast.CallExpr, bool) { return nil, false } -func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []Lint { - lints := []Lint{} +func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []analysis.Diagnostic { + lints := []analysis.Diagnostic{} for expr := range info.Types { // Find == and != operations. @@ -165,7 +187,7 @@ func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []Lint { continue } - lints = append(lints, Lint{ + lints = append(lints, analysis.Diagnostic{ Message: fmt.Sprintf("comparing with %s will fail on wrapped errors. Use errors.Is to check for a specific error", binExpr.Op), Pos: binExpr.Pos(), }) @@ -190,7 +212,7 @@ func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []Lint { } if switchComparesNonNil(switchStmt) { - lints = append(lints, Lint{ + lints = append(lints, analysis.Diagnostic{ Message: "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors", Pos: switchStmt.Pos(), }) @@ -266,8 +288,8 @@ func switchComparesNonNil(switchStmt *ast.SwitchStmt) bool { return false } -func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []Lint { - lints := []Lint{} +func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []analysis.Diagnostic { + lints := []analysis.Diagnostic{} for expr := range info.Types { // Find type assertions. @@ -281,7 +303,7 @@ func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []Lint { continue } - lints = append(lints, Lint{ + lints = append(lints, analysis.Diagnostic{ Message: "type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors", Pos: typeAssert.Pos(), }) @@ -308,7 +330,7 @@ func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []Lint { continue } - lints = append(lints, Lint{ + lints = append(lints, analysis.Diagnostic{ Message: "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors", Pos: typeAssert.Pos(), }) diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go index d9a935ff2..973752592 100644 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go +++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go @@ -25,12 +25,14 @@ func verbOrder(verbs []verb, numArgs int) [][]verb { } type verb struct { - format string - index int + format string + formatOffset int + index int } type printfParser struct { str string + at int } func (pp *printfParser) ParseAllVerbs() ([]verb, error) { @@ -80,7 +82,7 @@ func (pp *printfParser) parseVerb() (*verb, error) { format := pp.next() - return &verb{format: string(format), index: index}, nil + return &verb{format: string(format), formatOffset: pp.at - 1, index: index}, nil } func (pp *printfParser) parseIndex() (int, error) { @@ -96,6 +98,7 @@ func (pp *printfParser) parseIndex() (int, error) { return -1, err } pp.str = pp.str[end+1:] + pp.at += end + 1 return index, nil } @@ -114,6 +117,7 @@ func (pp *printfParser) skipToPercent() error { return io.EOF } pp.str = pp.str[i:] + pp.at += i return nil } @@ -130,5 +134,6 @@ func (pp *printfParser) next() rune { } r := rune(pp.str[0]) pp.str = pp.str[1:] + pp.at++ return r } |
