David López 37e6995b45 lintpack/gocritic: update lintpack & gocritic versions
update lintpack & gocritic versions to support all the new gocritic checks
2018-12-22 15:34:16 +03:00

93 lines
2.3 KiB
Go

package checkers
import (
"go/ast"
"go/types"
"strings"
"github.com/go-lintpack/lintpack"
"golang.org/x/tools/go/ast/astutil"
)
// isUnitTestFunc reports whether FuncDecl declares testing function.
func isUnitTestFunc(ctx *lintpack.CheckerContext, fn *ast.FuncDecl) bool {
if !strings.HasPrefix(fn.Name.Name, "Test") {
return false
}
typ := ctx.TypesInfo.TypeOf(fn.Name)
if sig, ok := typ.(*types.Signature); ok {
return sig.Results().Len() == 0 &&
sig.Params().Len() == 1 &&
sig.Params().At(0).Type().String() == "*testing.T"
}
return false
}
// qualifiedName returns called expr fully-quallified name.
//
// It works for simple identifiers like f => "f" and identifiers
// from other package like pkg.f => "pkg.f".
//
// For all unexpected expressions returns empty string.
func qualifiedName(x ast.Expr) string {
switch x := x.(type) {
case *ast.SelectorExpr:
pkg, ok := x.X.(*ast.Ident)
if !ok {
return ""
}
return pkg.Name + "." + x.Sel.Name
case *ast.Ident:
return x.Name
default:
return ""
}
}
// identOf returns identifier for x that can be used to obtain associated types.Object.
// Returns nil for expressions that yield temporary results, like `f().field`.
func identOf(x ast.Node) *ast.Ident {
switch x := x.(type) {
case *ast.Ident:
return x
case *ast.SelectorExpr:
return identOf(x.Sel)
case *ast.TypeAssertExpr:
// x.(type) - x may contain ident.
return identOf(x.X)
case *ast.IndexExpr:
// x[i] - x may contain ident.
return identOf(x.X)
case *ast.StarExpr:
// *x - x may contain ident.
return identOf(x.X)
case *ast.SliceExpr:
// x[:] - x may contain ident.
return identOf(x.X)
default:
// Note that this function is not comprehensive.
return nil
}
}
// findNode applies pred for root and all it's childs until it returns true.
// Matched node is returned.
// If none of the nodes matched predicate, nil is returned.
func findNode(root ast.Node, pred func(ast.Node) bool) ast.Node {
var found ast.Node
astutil.Apply(root, nil, func(cur *astutil.Cursor) bool {
if pred(cur.Node()) {
found = cur.Node()
return false
}
return true
})
return found
}
// containsNode reports whether `findNode(root, pred)!=nil`.
func containsNode(root ast.Node, pred func(ast.Node) bool) bool {
return findNode(root, pred) != nil
}