1package errorlint
2
3import (
4	"flag"
5	"sort"
6
7	"golang.org/x/tools/go/analysis"
8)
9
10func NewAnalyzer() *analysis.Analyzer {
11	return &analysis.Analyzer{
12		Name:  "errorlint",
13		Doc:   "Source code linter for Go software that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.",
14		Run:   run,
15		Flags: flagSet,
16	}
17}
18
19var (
20	flagSet         flag.FlagSet
21	checkComparison bool
22	checkAsserts    bool
23	checkErrorf     bool
24)
25
26func init() {
27	flagSet.BoolVar(&checkComparison, "comparison", true, "Check for plain error comparisons")
28	flagSet.BoolVar(&checkAsserts, "asserts", true, "Check for plain type assertions and type switches")
29	flagSet.BoolVar(&checkErrorf, "errorf", false, "Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats")
30}
31
32func run(pass *analysis.Pass) (interface{}, error) {
33	lints := []Lint{}
34	if checkComparison {
35		l := LintErrorComparisons(pass.Fset, *pass.TypesInfo)
36		lints = append(lints, l...)
37	}
38	if checkAsserts {
39		l := LintErrorTypeAssertions(pass.Fset, *pass.TypesInfo)
40		lints = append(lints, l...)
41	}
42	if checkErrorf {
43		l := LintFmtErrorfCalls(pass.Fset, *pass.TypesInfo)
44		lints = append(lints, l...)
45	}
46	sort.Sort(ByPosition(lints))
47
48	for _, l := range lints {
49		pass.Report(analysis.Diagnostic{Pos: l.Pos, Message: l.Message})
50	}
51	return nil, nil
52}
53