aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-lintpack/lintpack/astwalk
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-07-04 11:12:55 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-07-04 15:05:30 +0200
commitc7d7f10bdff703e4a3c0414e8a33d4e45c91eb35 (patch)
tree0dff0ee1f98dbfa3ad8776112053a450d176592b /vendor/github.com/go-lintpack/lintpack/astwalk
parent9573094ce235bd9afe88f5da27a47dd6bcc1e13b (diff)
go.mod: vendor golangci-lint
Diffstat (limited to 'vendor/github.com/go-lintpack/lintpack/astwalk')
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/comment_walker.go41
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/doc_comment_walker.go48
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/expr_walker.go29
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/func_decl_walker.go21
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/local_comment_walker.go32
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/local_def_visitor.go51
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/local_def_walker.go118
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/local_expr_walker.go27
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/stmt_list_walker.go31
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/stmt_walker.go27
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/type_expr_walker.go114
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/visitor.go80
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/walk_handler.go34
-rw-r--r--vendor/github.com/go-lintpack/lintpack/astwalk/walker.go57
14 files changed, 710 insertions, 0 deletions
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/comment_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/comment_walker.go
new file mode 100644
index 000000000..6c60e3fed
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/comment_walker.go
@@ -0,0 +1,41 @@
+package astwalk
+
+import (
+ "go/ast"
+ "strings"
+)
+
+type commentWalker struct {
+ visitor CommentVisitor
+}
+
+func (w *commentWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, cg := range f.Comments {
+ visitCommentGroups(cg, w.visitor.VisitComment)
+ }
+}
+
+func visitCommentGroups(cg *ast.CommentGroup, visit func(*ast.CommentGroup)) {
+ var group []*ast.Comment
+ visitGroup := func(list []*ast.Comment) {
+ if len(list) == 0 {
+ return
+ }
+ cg := &ast.CommentGroup{List: list}
+ visit(cg)
+ }
+ for _, comment := range cg.List {
+ if strings.HasPrefix(comment.Text, "/*") {
+ visitGroup(group)
+ group = group[:0]
+ visitGroup([]*ast.Comment{comment})
+ } else {
+ group = append(group, comment)
+ }
+ }
+ visitGroup(group)
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/doc_comment_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/doc_comment_walker.go
new file mode 100644
index 000000000..39b536508
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/doc_comment_walker.go
@@ -0,0 +1,48 @@
+package astwalk
+
+import (
+ "go/ast"
+)
+
+type docCommentWalker struct {
+ visitor DocCommentVisitor
+}
+
+func (w *docCommentWalker) WalkFile(f *ast.File) {
+ for _, decl := range f.Decls {
+ switch decl := decl.(type) {
+ case *ast.FuncDecl:
+ if decl.Doc != nil {
+ w.visitor.VisitDocComment(decl.Doc)
+ }
+ case *ast.GenDecl:
+ if decl.Doc != nil {
+ w.visitor.VisitDocComment(decl.Doc)
+ }
+ for _, spec := range decl.Specs {
+ switch spec := spec.(type) {
+ case *ast.ImportSpec:
+ if spec.Doc != nil {
+ w.visitor.VisitDocComment(spec.Doc)
+ }
+ case *ast.ValueSpec:
+ if spec.Doc != nil {
+ w.visitor.VisitDocComment(spec.Doc)
+ }
+ case *ast.TypeSpec:
+ if spec.Doc != nil {
+ w.visitor.VisitDocComment(spec.Doc)
+ }
+ ast.Inspect(spec.Type, func(n ast.Node) bool {
+ if n, ok := n.(*ast.Field); ok {
+ if n.Doc != nil {
+ w.visitor.VisitDocComment(n.Doc)
+ }
+ }
+ return true
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/expr_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/expr_walker.go
new file mode 100644
index 000000000..64098b2b7
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/expr_walker.go
@@ -0,0 +1,29 @@
+package astwalk
+
+import "go/ast"
+
+type exprWalker struct {
+ visitor ExprVisitor
+}
+
+func (w *exprWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, decl := range f.Decls {
+ if decl, ok := decl.(*ast.FuncDecl); ok {
+ if !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ }
+
+ ast.Inspect(decl, func(x ast.Node) bool {
+ if x, ok := x.(ast.Expr); ok {
+ w.visitor.VisitExpr(x)
+ return !w.visitor.skipChilds()
+ }
+ return true
+ })
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/func_decl_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/func_decl_walker.go
new file mode 100644
index 000000000..90d921f6f
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/func_decl_walker.go
@@ -0,0 +1,21 @@
+package astwalk
+
+import "go/ast"
+
+type funcDeclWalker struct {
+ visitor FuncDeclVisitor
+}
+
+func (w *funcDeclWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, decl := range f.Decls {
+ decl, ok := decl.(*ast.FuncDecl)
+ if !ok || !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ w.visitor.VisitFuncDecl(decl)
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/local_comment_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/local_comment_walker.go
new file mode 100644
index 000000000..e042f0d5e
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/local_comment_walker.go
@@ -0,0 +1,32 @@
+package astwalk
+
+import (
+ "go/ast"
+)
+
+type localCommentWalker struct {
+ visitor LocalCommentVisitor
+}
+
+func (w *localCommentWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, decl := range f.Decls {
+ decl, ok := decl.(*ast.FuncDecl)
+ if !ok || !w.visitor.EnterFunc(decl) {
+ continue
+ }
+
+ for _, cg := range f.Comments {
+ // Not sure that decls/comments are sorted
+ // by positions, so do a naive full scan for now.
+ if cg.Pos() < decl.Pos() || cg.Pos() > decl.End() {
+ continue
+ }
+
+ visitCommentGroups(cg, w.visitor.VisitLocalComment)
+ }
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/local_def_visitor.go b/vendor/github.com/go-lintpack/lintpack/astwalk/local_def_visitor.go
new file mode 100644
index 000000000..bed0f44ab
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/local_def_visitor.go
@@ -0,0 +1,51 @@
+package astwalk
+
+import (
+ "go/ast"
+)
+
+// LocalDefVisitor visits every name definitions inside a function.
+//
+// Next elements are considered as name definitions:
+// - Function parameters (input, output, receiver)
+// - Every LHS of ":=" assignment that defines a new name
+// - Every local var/const declaration.
+//
+// NOTE: this visitor is experimental.
+// This is also why it lives in a separate file.
+type LocalDefVisitor interface {
+ walkerEvents
+ VisitLocalDef(Name, ast.Expr)
+}
+
+type (
+ // NameKind describes what kind of name Name object holds.
+ NameKind int
+
+ // Name holds ver/const/param definition symbol info.
+ Name struct {
+ ID *ast.Ident
+ Kind NameKind
+
+ // Index is NameVar-specific field that is used to
+ // specify nth tuple element being assigned to the name.
+ Index int
+ }
+)
+
+// NOTE: set of name kinds is not stable and may change over time.
+//
+// TODO(quasilyte): is NameRecv/NameParam/NameResult granularity desired?
+// TODO(quasilyte): is NameVar/NameBind (var vs :=) granularity desired?
+const (
+ // NameParam is function/method receiver/input/output name.
+ // Initializing expression is always nil.
+ NameParam NameKind = iota
+ // NameVar is var or ":=" declared name.
+ // Initizlizing expression may be nil for var-declared names
+ // without explicit initializing expression.
+ NameVar
+ // NameConst is const-declared name.
+ // Initializing expression is never nil.
+ NameConst
+)
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/local_def_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/local_def_walker.go
new file mode 100644
index 000000000..f6808cbb4
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/local_def_walker.go
@@ -0,0 +1,118 @@
+package astwalk
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+)
+
+type localDefWalker struct {
+ visitor LocalDefVisitor
+ info *types.Info
+}
+
+func (w *localDefWalker) WalkFile(f *ast.File) {
+ for _, decl := range f.Decls {
+ decl, ok := decl.(*ast.FuncDecl)
+ if !ok || !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ w.walkFunc(decl)
+ }
+}
+
+func (w *localDefWalker) walkFunc(decl *ast.FuncDecl) {
+ w.walkSignature(decl)
+ w.walkFuncBody(decl)
+}
+
+func (w *localDefWalker) walkFuncBody(decl *ast.FuncDecl) {
+ ast.Inspect(decl.Body, func(x ast.Node) bool {
+ switch x := x.(type) {
+ case *ast.AssignStmt:
+ if x.Tok != token.DEFINE {
+ return false
+ }
+ if len(x.Lhs) != len(x.Rhs) {
+ // Multi-value assignment.
+ // Invariant: there is only 1 RHS.
+ for i, lhs := range x.Lhs {
+ id, ok := lhs.(*ast.Ident)
+ if !ok || w.info.Defs[id] == nil {
+ continue
+ }
+ def := Name{ID: id, Kind: NameVar, Index: i}
+ w.visitor.VisitLocalDef(def, x.Rhs[0])
+ }
+ } else {
+ // Simple 1-1 assignments.
+ for i, lhs := range x.Lhs {
+ id, ok := lhs.(*ast.Ident)
+ if !ok || w.info.Defs[id] == nil {
+ continue
+ }
+ def := Name{ID: id, Kind: NameVar}
+ w.visitor.VisitLocalDef(def, x.Rhs[i])
+ }
+ }
+ return false
+
+ case *ast.GenDecl:
+ // Decls always introduce new names.
+ for _, spec := range x.Specs {
+ spec, ok := spec.(*ast.ValueSpec)
+ if !ok { // Ignore type/import specs
+ return false
+ }
+ switch {
+ case len(spec.Values) == 0:
+ // var-specific decls without explicit init.
+ for _, id := range spec.Names {
+ def := Name{ID: id, Kind: NameVar}
+ w.visitor.VisitLocalDef(def, nil)
+ }
+ case len(spec.Names) != len(spec.Values):
+ // var-specific decls that assign tuple results.
+ for i, id := range spec.Names {
+ def := Name{ID: id, Kind: NameVar, Index: i}
+ w.visitor.VisitLocalDef(def, spec.Values[0])
+ }
+ default:
+ // Can be either var or const decl.
+ kind := NameVar
+ if x.Tok == token.CONST {
+ kind = NameConst
+ }
+ for i, id := range spec.Names {
+ def := Name{ID: id, Kind: kind}
+ w.visitor.VisitLocalDef(def, spec.Values[i])
+ }
+ }
+ }
+ return false
+ }
+
+ return true
+ })
+}
+
+func (w *localDefWalker) walkSignature(decl *ast.FuncDecl) {
+ for _, p := range decl.Type.Params.List {
+ for _, id := range p.Names {
+ def := Name{ID: id, Kind: NameParam}
+ w.visitor.VisitLocalDef(def, nil)
+ }
+ }
+ if decl.Type.Results != nil {
+ for _, p := range decl.Type.Results.List {
+ for _, id := range p.Names {
+ def := Name{ID: id, Kind: NameParam}
+ w.visitor.VisitLocalDef(def, nil)
+ }
+ }
+ }
+ if decl.Recv != nil && len(decl.Recv.List[0].Names) != 0 {
+ def := Name{ID: decl.Recv.List[0].Names[0], Kind: NameParam}
+ w.visitor.VisitLocalDef(def, nil)
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/local_expr_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/local_expr_walker.go
new file mode 100644
index 000000000..951fd97e5
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/local_expr_walker.go
@@ -0,0 +1,27 @@
+package astwalk
+
+import "go/ast"
+
+type localExprWalker struct {
+ visitor LocalExprVisitor
+}
+
+func (w *localExprWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, decl := range f.Decls {
+ decl, ok := decl.(*ast.FuncDecl)
+ if !ok || !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ ast.Inspect(decl.Body, func(x ast.Node) bool {
+ if x, ok := x.(ast.Expr); ok {
+ w.visitor.VisitLocalExpr(x)
+ return !w.visitor.skipChilds()
+ }
+ return true
+ })
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/stmt_list_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/stmt_list_walker.go
new file mode 100644
index 000000000..1cc0493a4
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/stmt_list_walker.go
@@ -0,0 +1,31 @@
+package astwalk
+
+import "go/ast"
+
+type stmtListWalker struct {
+ visitor StmtListVisitor
+}
+
+func (w *stmtListWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, decl := range f.Decls {
+ decl, ok := decl.(*ast.FuncDecl)
+ if !ok || !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ ast.Inspect(decl.Body, func(x ast.Node) bool {
+ switch x := x.(type) {
+ case *ast.BlockStmt:
+ w.visitor.VisitStmtList(x.List)
+ case *ast.CaseClause:
+ w.visitor.VisitStmtList(x.Body)
+ case *ast.CommClause:
+ w.visitor.VisitStmtList(x.Body)
+ }
+ return !w.visitor.skipChilds()
+ })
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/stmt_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/stmt_walker.go
new file mode 100644
index 000000000..722eeb116
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/stmt_walker.go
@@ -0,0 +1,27 @@
+package astwalk
+
+import "go/ast"
+
+type stmtWalker struct {
+ visitor StmtVisitor
+}
+
+func (w *stmtWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, decl := range f.Decls {
+ decl, ok := decl.(*ast.FuncDecl)
+ if !ok || !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ ast.Inspect(decl.Body, func(x ast.Node) bool {
+ if x, ok := x.(ast.Stmt); ok {
+ w.visitor.VisitStmt(x)
+ return !w.visitor.skipChilds()
+ }
+ return true
+ })
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/type_expr_walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/type_expr_walker.go
new file mode 100644
index 000000000..24c150084
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/type_expr_walker.go
@@ -0,0 +1,114 @@
+package astwalk
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+
+ "github.com/go-toolsmith/astp"
+ "github.com/go-toolsmith/typep"
+)
+
+type typeExprWalker struct {
+ visitor TypeExprVisitor
+ info *types.Info
+}
+
+func (w *typeExprWalker) WalkFile(f *ast.File) {
+ if !w.visitor.EnterFile(f) {
+ return
+ }
+
+ for _, decl := range f.Decls {
+ if decl, ok := decl.(*ast.FuncDecl); ok {
+ if !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ }
+ switch decl := decl.(type) {
+ case *ast.FuncDecl:
+ if !w.visitor.EnterFunc(decl) {
+ continue
+ }
+ w.walkSignature(decl.Type)
+ ast.Inspect(decl.Body, w.walk)
+ case *ast.GenDecl:
+ if decl.Tok == token.IMPORT {
+ continue
+ }
+ ast.Inspect(decl, w.walk)
+ }
+ }
+}
+
+func (w *typeExprWalker) visit(x ast.Expr) bool {
+ w.visitor.VisitTypeExpr(x)
+ return !w.visitor.skipChilds()
+}
+
+func (w *typeExprWalker) walk(x ast.Node) bool {
+ switch x := x.(type) {
+ case *ast.ParenExpr:
+ if typep.IsTypeExpr(w.info, x.X) {
+ return w.visit(x)
+ }
+ return true
+ case *ast.CallExpr:
+ // Pointer conversions require parenthesis around pointer type.
+ // These casts are represented as call expressions.
+ // Because it's impossible for the visitor to distinguish such
+ // "required" parenthesis, walker skips outmost parenthesis in such cases.
+ return w.inspectInner(x.Fun)
+ case *ast.SelectorExpr:
+ // Like with conversions, method expressions are another special.
+ return w.inspectInner(x.X)
+ case *ast.StarExpr:
+ if typep.IsTypeExpr(w.info, x.X) {
+ return w.visit(x)
+ }
+ return true
+ case *ast.MapType:
+ return w.visit(x)
+ case *ast.FuncType:
+ return w.visit(x)
+ case *ast.StructType:
+ return w.visit(x)
+ case *ast.InterfaceType:
+ if !w.visit(x) {
+ return false
+ }
+ for _, method := range x.Methods.List {
+ switch x := method.Type.(type) {
+ case *ast.FuncType:
+ w.walkSignature(x)
+ default:
+ // Embedded interface.
+ w.walk(x)
+ }
+ }
+ return false
+ case *ast.ArrayType:
+ return w.visit(x)
+ }
+ return true
+}
+
+func (w *typeExprWalker) inspectInner(x ast.Expr) bool {
+ parens, ok := x.(*ast.ParenExpr)
+ if ok && typep.IsTypeExpr(w.info, parens.X) && astp.IsStarExpr(parens.X) {
+ ast.Inspect(parens.X, w.walk)
+ return false
+ }
+ return true
+}
+
+func (w *typeExprWalker) walkSignature(typ *ast.FuncType) {
+ for _, p := range typ.Params.List {
+ ast.Inspect(p.Type, w.walk)
+ }
+ if typ.Results != nil {
+ for _, p := range typ.Results.List {
+ ast.Inspect(p.Type, w.walk)
+ }
+ }
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/visitor.go b/vendor/github.com/go-lintpack/lintpack/astwalk/visitor.go
new file mode 100644
index 000000000..9f973a2b3
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/visitor.go
@@ -0,0 +1,80 @@
+package astwalk
+
+import (
+ "go/ast"
+)
+
+// Visitor interfaces.
+type (
+ // DocCommentVisitor visits every doc-comment.
+ // Does not visit doc-comments for function-local definitions (types, etc).
+ // Also does not visit package doc-comment (file-level doc-comments).
+ DocCommentVisitor interface {
+ VisitDocComment(*ast.CommentGroup)
+ }
+
+ // FuncDeclVisitor visits every top-level function declaration.
+ FuncDeclVisitor interface {
+ walkerEvents
+ VisitFuncDecl(*ast.FuncDecl)
+ }
+
+ // ExprVisitor visits every expression inside AST file.
+ ExprVisitor interface {
+ walkerEvents
+ VisitExpr(ast.Expr)
+ }
+
+ // LocalExprVisitor visits every expression inside function body.
+ LocalExprVisitor interface {
+ walkerEvents
+ VisitLocalExpr(ast.Expr)
+ }
+
+ // StmtListVisitor visits every statement list inside function body.
+ // This includes block statement bodies as well as implicit blocks
+ // introduced by case clauses and alike.
+ StmtListVisitor interface {
+ walkerEvents
+ VisitStmtList([]ast.Stmt)
+ }
+
+ // StmtVisitor visits every statement inside function body.
+ StmtVisitor interface {
+ walkerEvents
+ VisitStmt(ast.Stmt)
+ }
+
+ // TypeExprVisitor visits every type describing expression.
+ // It also traverses struct types and interface types to run
+ // checker over their fields/method signatures.
+ TypeExprVisitor interface {
+ walkerEvents
+ VisitTypeExpr(ast.Expr)
+ }
+
+ // LocalCommentVisitor visits every comment inside function body.
+ LocalCommentVisitor interface {
+ walkerEvents
+ VisitLocalComment(*ast.CommentGroup)
+ }
+
+ // CommentVisitor visits every comment.
+ CommentVisitor interface {
+ walkerEvents
+ VisitComment(*ast.CommentGroup)
+ }
+)
+
+// walkerEvents describes common hooks available for most visitor types.
+type walkerEvents interface {
+ // EnterFile is called for every file that is about to be traversed.
+ // If false is returned, file is not visited.
+ EnterFile(*ast.File) bool
+
+ // EnterFunc is called for every function declaration that is about
+ // to be traversed. If false is returned, function is not visited.
+ EnterFunc(*ast.FuncDecl) bool
+
+ skipChilds() bool
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/walk_handler.go b/vendor/github.com/go-lintpack/lintpack/astwalk/walk_handler.go
new file mode 100644
index 000000000..1f6e948d5
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/walk_handler.go
@@ -0,0 +1,34 @@
+package astwalk
+
+import (
+ "go/ast"
+)
+
+// WalkHandler is a type to be embedded into every checker
+// that uses astwalk walkers.
+type WalkHandler struct {
+ // SkipChilds controls whether currently analyzed
+ // node childs should be traversed.
+ //
+ // Value is reset after each visitor invocation,
+ // so there is no need to set value back to false.
+ SkipChilds bool
+}
+
+// EnterFile is a default walkerEvents.EnterFile implementation
+// that reports every file as accepted candidate for checking.
+func (w *WalkHandler) EnterFile(f *ast.File) bool {
+ return true
+}
+
+// EnterFunc is a default walkerEvents.EnterFunc implementation
+// that skips extern function (ones that do not have body).
+func (w *WalkHandler) EnterFunc(decl *ast.FuncDecl) bool {
+ return decl.Body != nil
+}
+
+func (w *WalkHandler) skipChilds() bool {
+ v := w.SkipChilds
+ w.SkipChilds = false
+ return v
+}
diff --git a/vendor/github.com/go-lintpack/lintpack/astwalk/walker.go b/vendor/github.com/go-lintpack/lintpack/astwalk/walker.go
new file mode 100644
index 000000000..fddae710a
--- /dev/null
+++ b/vendor/github.com/go-lintpack/lintpack/astwalk/walker.go
@@ -0,0 +1,57 @@
+package astwalk
+
+import (
+ "go/types"
+
+ "github.com/go-lintpack/lintpack"
+)
+
+// WalkerForFuncDecl returns file walker implementation for FuncDeclVisitor.
+func WalkerForFuncDecl(v FuncDeclVisitor) lintpack.FileWalker {
+ return &funcDeclWalker{visitor: v}
+}
+
+// WalkerForExpr returns file walker implementation for ExprVisitor.
+func WalkerForExpr(v ExprVisitor) lintpack.FileWalker {
+ return &exprWalker{visitor: v}
+}
+
+// WalkerForLocalExpr returns file walker implementation for LocalExprVisitor.
+func WalkerForLocalExpr(v LocalExprVisitor) lintpack.FileWalker {
+ return &localExprWalker{visitor: v}
+}
+
+// WalkerForStmtList returns file walker implementation for StmtListVisitor.
+func WalkerForStmtList(v StmtListVisitor) lintpack.FileWalker {
+ return &stmtListWalker{visitor: v}
+}
+
+// WalkerForStmt returns file walker implementation for StmtVisitor.
+func WalkerForStmt(v StmtVisitor) lintpack.FileWalker {
+ return &stmtWalker{visitor: v}
+}
+
+// WalkerForTypeExpr returns file walker implementation for TypeExprVisitor.
+func WalkerForTypeExpr(v TypeExprVisitor, info *types.Info) lintpack.FileWalker {
+ return &typeExprWalker{visitor: v, info: info}
+}
+
+// WalkerForLocalComment returns file walker implementation for LocalCommentVisitor.
+func WalkerForLocalComment(v LocalCommentVisitor) lintpack.FileWalker {
+ return &localCommentWalker{visitor: v}
+}
+
+// WalkerForComment returns file walker implementation for CommentVisitor.
+func WalkerForComment(v CommentVisitor) lintpack.FileWalker {
+ return &commentWalker{visitor: v}
+}
+
+// WalkerForDocComment returns file walker implementation for DocCommentVisitor.
+func WalkerForDocComment(v DocCommentVisitor) lintpack.FileWalker {
+ return &docCommentWalker{visitor: v}
+}
+
+// WalkerForLocalDef returns file walker implementation for LocalDefVisitor.
+func WalkerForLocalDef(v LocalDefVisitor, info *types.Info) lintpack.FileWalker {
+ return &localDefWalker{visitor: v, info: info}
+}