github.com/prysmaticlabs/prysm@v1.4.4/tools/analyzers/slicedirect/analyzer.go (about) 1 // Package slicedirect implements a static analyzer to ensure that code does not contain 2 // applications of [:] on expressions which are already slices. 3 package slicedirect 4 5 import ( 6 "errors" 7 "go/ast" 8 "go/types" 9 10 "golang.org/x/tools/go/analysis" 11 "golang.org/x/tools/go/analysis/passes/inspect" 12 "golang.org/x/tools/go/ast/inspector" 13 ) 14 15 // Doc explaining the tool. 16 const Doc = "Tool to detect unnecessary slice-to-slice conversion by applying [:] to a slice expression." 17 18 // Analyzer runs static analysis. 19 var Analyzer = &analysis.Analyzer{ 20 Name: "slicedirect", 21 Doc: Doc, 22 Requires: []*analysis.Analyzer{inspect.Analyzer}, 23 Run: run, 24 } 25 26 func run(pass *analysis.Pass) (interface{}, error) { 27 inspection, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) 28 if !ok { 29 return nil, errors.New("analyzer is not type *inspector.Inspector") 30 } 31 32 nodeFilter := []ast.Node{ 33 (*ast.SliceExpr)(nil), 34 } 35 36 typeInfo := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)} 37 38 inspection.Preorder(nodeFilter, func(node ast.Node) { 39 sliceExpr, ok := node.(*ast.SliceExpr) 40 if !ok { 41 return 42 } 43 44 if err := types.CheckExpr(pass.Fset, pass.Pkg, sliceExpr.X.Pos(), sliceExpr.X, &typeInfo); err != nil { 45 return 46 } 47 48 if sliceExpr.Low != nil || sliceExpr.High != nil { 49 return 50 } 51 52 switch x := typeInfo.Types[sliceExpr.X].Type.(type) { 53 case *types.Slice: 54 pass.Reportf(sliceExpr.Pos(), "Expression is already a slice.") 55 case *types.Basic: 56 if x.String() == "string" { 57 pass.Reportf(sliceExpr.Pos(), "Expression is already a slice.") 58 } 59 } 60 }) 61 62 return nil, nil 63 }