-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinspector.go
112 lines (96 loc) · 2.29 KB
/
inspector.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package astquery
import (
"go/ast"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/go/ast/inspector"
)
// Inspector is wrapper of *golang.org/x/go/ast/inspector.Inspector.
type Inspector struct {
*inspector.Inspector
}
// NewInspector creates an Inspector.
func NewInspector(files []*ast.File) *Inspector {
return &Inspector{inspector.New(files)}
}
// Children returns children of the given node.
func (in *Inspector) Children(n ast.Node) []ast.Node {
if n == nil {
return nil
}
var children []ast.Node
ast.Inspect(n, func(_n ast.Node) bool {
if _n != nil && n != _n {
children = append(children, _n)
return false
}
return true
})
if len(children) != 0 {
return children
}
return children
}
// Stack returns a stack which contains between the root node and the given node.
// The stack's first element is the root node and last element is the given node.
func (in *Inspector) Stack(n ast.Node) []ast.Node {
var stack []ast.Node
in.WithStack(nil, func(_n ast.Node, push bool, _stack []ast.Node) bool {
if !push || stack != nil {
return false
}
if n == _n {
stack = make([]ast.Node, len(_stack))
copy(stack, _stack)
return false
}
return true
})
return stack
}
// Path returns a path to the given node from the root node.
// The path's first element is the given node and last element is the root node.
func (in *Inspector) Path(n ast.Node) []ast.Node {
stack := in.Stack(n)
if stack == nil {
return nil
}
path := make([]ast.Node, len(stack))
for i := range path {
path[i] = stack[len(stack)-1-i]
}
return path
}
// Parent returns a parent node of the given node.
func (in *Inspector) Parent(n ast.Node) ast.Node {
path := in.Path(n)
if len(path) <= 1 {
return nil
}
return path[1]
}
// Name returns parent's field name.
func (in *Inspector) Name(n ast.Node) string {
var name string
parent := in.Parent(n)
astutil.Apply(parent, func(cur *astutil.Cursor) bool {
if n == cur.Node() {
name = cur.Name()
return false
}
return true
}, nil)
return name
}
// Index returns parent's field index.
func (in *Inspector) Index(n ast.Node) int {
var index int
parent := in.Parent(n)
astutil.Apply(parent, func(cur *astutil.Cursor) bool {
if n == cur.Node() {
index = cur.Index()
return false
}
return true
}, nil)
return index
}