s1010.go raw
1 package s1010
2
3 import (
4 "go/ast"
5
6 "honnef.co/go/tools/analysis/code"
7 "honnef.co/go/tools/analysis/edit"
8 "honnef.co/go/tools/analysis/facts/generated"
9 "honnef.co/go/tools/analysis/lint"
10 "honnef.co/go/tools/analysis/report"
11 "honnef.co/go/tools/pattern"
12
13 "golang.org/x/tools/go/analysis"
14 "golang.org/x/tools/go/analysis/passes/inspect"
15 )
16
17 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
18 Analyzer: &analysis.Analyzer{
19 Name: "S1010",
20 Run: run,
21 Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
22 },
23 Doc: &lint.RawDocumentation{
24 Title: `Omit default slice index`,
25 Text: `When slicing, the second index defaults to the length of the value,
26 making \'s[n:len(s)]\' and \'s[n:]\' equivalent.`,
27 Since: "2017.1",
28 MergeIf: lint.MergeIfAny,
29 },
30 })
31
32 var Analyzer = SCAnalyzer.Analyzer
33
34 var checkSlicingQ = pattern.MustParse(`(SliceExpr x@(Object _) low (CallExpr (Builtin "len") [x]) nil)`)
35
36 func run(pass *analysis.Pass) (interface{}, error) {
37 fn := func(node ast.Node) {
38 if _, ok := code.Match(pass, checkSlicingQ, node); ok {
39 expr := node.(*ast.SliceExpr)
40 report.Report(pass, expr.High,
41 "should omit second index in slice, s[a:len(s)] is identical to s[a:]",
42 report.FilterGenerated(),
43 report.Fixes(edit.Fix("simplify slice expression", edit.Delete(expr.High))))
44 }
45 }
46 code.Preorder(pass, fn, (*ast.SliceExpr)(nil))
47 return nil, nil
48 }
49