github.com/prysmaticlabs/prysm@v1.4.4/tools/analyzers/nop/analyzer.go (about)

     1  // Package nop implements a static analyzer to ensure that code does not contain no-op instructions.
     2  package nop
     3  
     4  import (
     5  	"errors"
     6  	"go/ast"
     7  	"go/token"
     8  
     9  	"golang.org/x/tools/go/analysis"
    10  	"golang.org/x/tools/go/analysis/passes/inspect"
    11  	"golang.org/x/tools/go/ast/inspector"
    12  )
    13  
    14  // Doc explaining the tool.
    15  const Doc = "Tool to detect no-op instructions."
    16  
    17  const message = "Found a no-op instruction that can be safely removed. " +
    18  	"It might be a result of writing code that does not do what was intended."
    19  
    20  // Analyzer runs static analysis.
    21  var Analyzer = &analysis.Analyzer{
    22  	Name:     "nop",
    23  	Doc:      Doc,
    24  	Requires: []*analysis.Analyzer{inspect.Analyzer},
    25  	Run:      run,
    26  }
    27  
    28  func run(pass *analysis.Pass) (interface{}, error) {
    29  	inspection, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
    30  	if !ok {
    31  		return nil, errors.New("analyzer is not type *inspector.Inspector")
    32  	}
    33  
    34  	nodeFilter := []ast.Node{
    35  		(*ast.StarExpr)(nil),
    36  		(*ast.UnaryExpr)(nil),
    37  	}
    38  
    39  	inspection.Preorder(nodeFilter, func(node ast.Node) {
    40  		switch expr := node.(type) {
    41  		case *ast.StarExpr:
    42  			unaryExpr, ok := expr.X.(*ast.UnaryExpr)
    43  			if !ok {
    44  				return
    45  			}
    46  
    47  			if unaryExpr.Op == token.AND {
    48  				pass.Reportf(expr.Star, message)
    49  			}
    50  		case *ast.UnaryExpr:
    51  			if expr.Op == token.AND {
    52  				if _, ok := expr.X.(*ast.StarExpr); ok {
    53  					pass.Reportf(expr.OpPos, message)
    54  				}
    55  			}
    56  		}
    57  	})
    58  
    59  	return nil, nil
    60  }