diff options
Diffstat (limited to 'vendor/github.com/Djarvur/go-err113/err113.go')
| -rw-r--r-- | vendor/github.com/Djarvur/go-err113/err113.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/vendor/github.com/Djarvur/go-err113/err113.go b/vendor/github.com/Djarvur/go-err113/err113.go new file mode 100644 index 000000000..e9d93a7a0 --- /dev/null +++ b/vendor/github.com/Djarvur/go-err113/err113.go @@ -0,0 +1,90 @@ +// Package err113 is a Golang linter to check the errors handling expressions +package err113 + +import ( + "bytes" + "go/ast" + "go/printer" + "go/token" + + "golang.org/x/tools/go/analysis" +) + +// NewAnalyzer creates a new analysis.Analyzer instance tuned to run err113 checks +func NewAnalyzer() *analysis.Analyzer { + return &analysis.Analyzer{ + Name: "err113", + Doc: "checks the error handling rules according to the Go 1.13 new error type", + Run: run, + } +} + +func run(pass *analysis.Pass) (interface{}, error) { + for _, file := range pass.Files { + tlds := enumerateFileDecls(file) + + ast.Inspect( + file, + func(n ast.Node) bool { + return inspectComparision(pass, n) && + inspectDefinition(pass, tlds, n) + }, + ) + } + + return nil, nil +} + +// render returns the pretty-print of the given node +func render(fset *token.FileSet, x interface{}) string { + var buf bytes.Buffer + if err := printer.Fprint(&buf, fset, x); err != nil { + panic(err) + } + + return buf.String() +} + +func enumerateFileDecls(f *ast.File) map[*ast.CallExpr]struct{} { + res := make(map[*ast.CallExpr]struct{}) + + var ces []*ast.CallExpr // nolint: prealloc + + for _, d := range f.Decls { + ces = append(ces, enumerateDeclVars(d)...) + } + + for _, ce := range ces { + res[ce] = struct{}{} + } + + return res +} + +func enumerateDeclVars(d ast.Decl) (res []*ast.CallExpr) { + td, ok := d.(*ast.GenDecl) + if !ok || td.Tok != token.VAR { + return nil + } + + for _, s := range td.Specs { + res = append(res, enumerateSpecValues(s)...) + } + + return res +} + +func enumerateSpecValues(s ast.Spec) (res []*ast.CallExpr) { + vs, ok := s.(*ast.ValueSpec) + if !ok { + return nil + } + + for _, v := range vs.Values { + if ce, ok := v.(*ast.CallExpr); ok { + res = append(res, ce) + } + } + + return res +} |
