This repository has been archived by the owner on Dec 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.go
92 lines (84 loc) · 2.27 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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
}