prysm-pulse/tools/analyzers/ineffassign/analyzer.go
Victor Farazdagi ecfdb354a7
Add new static analyzer: ineffassign (#7413)
* test defined

* first working impl

* register analyzer

* cleanup

* removes unused code

* secure rand in slasher/detection/testing

* Updates test

* fixes ineffassign type checks

* one more

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2020-10-02 23:56:18 +03:00

57 lines
1.4 KiB
Go

// Package ineffassign implements a static analyzer to ensure that there are no ineffectual
// assignments in source code.
package ineffassign
import (
"errors"
"go/ast"
"sort"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
)
// Doc explaining the tool.
const Doc = "Tool to make sure there are no ineffectual assignments in source code"
// Analyzer runs static analysis.
var Analyzer = &analysis.Analyzer{
Name: "ineffassign",
Doc: Doc,
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: run,
}
func run(pass *analysis.Pass) (interface{}, error) {
insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
if !ok {
return nil, errors.New("analyzer is not type *inspector.Inspector")
}
nodeFilter := []ast.Node{
(*ast.File)(nil),
}
insp.Preorder(nodeFilter, func(node ast.Node) {
f, ok := node.(*ast.File)
if !ok {
return
}
bld := &builder{vars: map[*ast.Object]*variable{}}
bld.walk(f)
chk := &checker{vars: bld.vars, seen: map[*block]bool{}}
for _, b := range bld.roots {
chk.check(b)
}
sort.Sort(chk.ineff)
// Report ineffectual assignments if any.
for _, id := range chk.ineff {
if id.Name != "ctx" { // We allow ineffectual assignment to ctx (to override ctx).
pass.Reportf(id.Pos(), "ineffectual assignment to %q", id.Name)
}
}
})
return nil, nil
}