-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile.go
97 lines (83 loc) · 1.95 KB
/
file.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
package main
import (
"go/ast"
"golang.org/x/tools/go/packages"
"os"
"strings"
)
type FuncMatcher func(*ast.FuncDecl) bool
var commentMatcher FuncMatcher = func(fnDecl *ast.FuncDecl) bool {
if fnDecl.Doc == nil || fnDecl.Doc.List == nil || len(fnDecl.Doc.List) == 0 {
return false
}
for _, comment := range fnDecl.Doc.List {
if strings.HasPrefix(comment.Text, "//go:generate genx handler") {
if fnDecl.Recv != nil {
return false
}
return true
}
}
return false
}
// GoFile represents a Go source file.
type GoFile struct {
Pkg *packages.Package
Imports map[string]string
Path string
Name string
AstFile *ast.File
}
func NewGoFile(pkg *packages.Package, astFile *ast.File, path string) *GoFile {
file := GoFile{
Pkg: pkg,
AstFile: astFile,
Path: path,
}
left := strings.LastIndex(path, string(os.PathSeparator))
if left != -1 {
file.Name = path[left+1:]
}
file.Name = file.Name[:len(file.Name)-len(".go")]
file.parseImportsName()
return &file
}
func (g *GoFile) GetDir() string {
index := strings.LastIndex(g.Path, string(os.PathSeparator))
if index == -1 {
return ""
}
return g.Path[:index]
}
func (g *GoFile) GetImportPkgByName(pkgName string) *packages.Package {
pkgPath := g.Imports[pkgName]
return g.Pkg.Imports[pkgPath]
}
func (g *GoFile) traversalFuncByMatch(matcher FuncMatcher, fn func(f *GoFunc)) {
for _, decl := range g.AstFile.Decls {
declFn, ok := decl.(*ast.FuncDecl)
if !ok {
continue
}
if !matcher(declFn) {
continue
}
handler := NewGoFunc(g, declFn)
fn(handler)
}
}
func (g *GoFile) parseImportsName() {
g.Imports = map[string]string{}
for _, imp := range g.AstFile.Imports {
pkgPath := imp.Path.Value
var pkgName string
if imp.Name != nil && imp.Name.Name != "" {
pkgName = imp.Name.Name
} else {
l := strings.LastIndex(imp.Path.Value, "/")
pkgName = imp.Path.Value[l+1:]
pkgName = strings.Trim(pkgName, "\"")
}
g.Imports[pkgName] = pkgPath
}
}