s1028.go (1449B)
1 package s1028 2 3 import ( 4 "honnef.co/go/tools/analysis/code" 5 "honnef.co/go/tools/analysis/edit" 6 "honnef.co/go/tools/analysis/facts/generated" 7 "honnef.co/go/tools/analysis/lint" 8 "honnef.co/go/tools/analysis/report" 9 "honnef.co/go/tools/pattern" 10 11 "golang.org/x/tools/go/analysis" 12 ) 13 14 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{ 15 Analyzer: &analysis.Analyzer{ 16 Name: "S1028", 17 Run: run, 18 Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...), 19 }, 20 Doc: &lint.RawDocumentation{ 21 Title: `Simplify error construction with \'fmt.Errorf\'`, 22 Before: `errors.New(fmt.Sprintf(...))`, 23 After: `fmt.Errorf(...)`, 24 Since: "2017.1", 25 MergeIf: lint.MergeIfAny, 26 }, 27 }) 28 29 var Analyzer = SCAnalyzer.Analyzer 30 31 var ( 32 checkErrorsNewSprintfQ = pattern.MustParse(`(CallExpr (Symbol "errors.New") [(CallExpr (Symbol "fmt.Sprintf") args)])`) 33 checkErrorsNewSprintfR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "fmt") (Ident "Errorf")) args)`) 34 ) 35 36 func run(pass *analysis.Pass) (any, error) { 37 for node, m := range code.Matches(pass, checkErrorsNewSprintfQ) { 38 edits := code.EditMatch(pass, node, m, checkErrorsNewSprintfR) 39 // TODO(dh): the suggested fix may leave an unused import behind 40 report.Report(pass, node, "should use fmt.Errorf(...) instead of errors.New(fmt.Sprintf(...))", 41 report.FilterGenerated(), 42 report.Fixes(edit.Fix("Use fmt.Errorf", edits...))) 43 } 44 return nil, nil 45 }