-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpackage.go
107 lines (88 loc) · 1.87 KB
/
package.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
package astrav
import (
"go/ast"
"go/token"
"go/types"
"math"
"golang.org/x/tools/go/packages"
)
// Package wraps ast.Package
type Package struct {
*ast.Package
baseNode
rawFiles map[string]*RawFile
defs map[*Ident]Node
info *types.Info
typesPkg *types.Package
pack *packages.Package
filled bool
}
// FuncDeclByName returns a func declaration by name
func (s *Package) FuncDeclByName(name string) *FuncDecl {
s.fill()
for k, v := range s.defs {
if k.Name == name {
if f, ok := v.(*FuncDecl); ok {
return f
}
}
}
return nil
}
// FuncDeclbyCallExpr returns a function declaration from its usage
func (s *Package) FuncDeclbyCallExpr(node *CallExpr) *FuncDecl {
ident := node.GetIdent()
if ident == nil {
return nil
}
return s.FuncDeclByName(ident.Name)
}
// GetRawFiles returns the raw files from the package.
func (s *Package) GetRawFiles() map[string][]byte {
var files = map[string][]byte{}
for key, file := range s.rawFiles {
files[key] = file.Source()
}
return files
}
func (s *Package) fill() {
if s.filled {
return
}
s.filled = true
s.defs = map[*Ident]Node{}
s.Walk(func(node Node) bool {
if n, ok := node.(*FuncDecl); ok {
ident := n.GetIdent()
if ident == nil {
return true
}
s.defs[ident] = n
}
return true
})
}
// // Pos returns the position of the package.
// func (s *Package) Pos() token.Pos {
// s.node.(*ast.Package).Pos()
// return s.pack.Types.Scope().Pos()
// }
// GetScope returns custom scope.
func (s *Package) GetScope() (Node, *types.Scope) {
minPos, maxPos := 0, 0
if len(s.rawFiles) != 0 {
minPos, maxPos = math.MaxInt, 0
}
for _, file := range s.rawFiles {
pos := file.Base()
end := pos + file.Size()
if pos < minPos {
minPos = pos
}
if maxPos < end {
maxPos = end
}
}
scope := types.NewScope(nil, token.Pos(minPos), token.Pos(maxPos), "")
return s, scope
}