/
reflect.go
93 lines (78 loc) · 1.83 KB
/
reflect.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
package main
// "reflect"
import (
"go/ast" //just for Type interface
"go/build"
"go/doc" //convient way to smush the ast and just grab names
"go/parser"
"go/token"
"os"
"strings"
)
var topics = MustReflectDefs()
func MustReflectDefs() map[string][]byte {
n, err := ReflectDefs()
if err != nil {
panic(err)
}
return n
}
func gofiles(fi os.FileInfo) bool {
return strings.HasSuffix(fi.Name(), ".go")
}
func ReflectDefs() (names map[string][]byte, err error) {
b, err := build.Import("reflect", "", 0)
if err != nil {
return nil, err
}
ts := token.NewFileSet()
p, err := parser.ParseDir(ts, b.Dir, gofiles, 0)
if err != nil {
return nil, err
}
pkg := doc.New(p["reflect"], "reflect", doc.AllMethods)
acc := []string{}
acc = values(pkg.Consts, acc)
acc = values(pkg.Vars, acc)
acc = funcs(pkg.Funcs, "reflect.", acc)
acc = types(pkg.Types, acc)
names = map[string][]byte{}
for _, name := range acc {
names[name] = []byte(name)
}
return names, nil
}
func values(vals []*doc.Value, acc []string) []string {
for _, v := range vals {
for _, name := range v.Names {
acc = append(acc, "reflect."+name)
}
}
return acc
}
func funcs(funcs []*doc.Func, prefix string, acc []string) []string {
for _, f := range funcs {
acc = append(acc, prefix+f.Name)
}
return acc
}
func types(types []*doc.Type, acc []string) []string {
for _, t := range types {
if strings.HasSuffix(t.Name, "Error") {
continue
}
acc = append(acc, "reflect."+t.Name)
if t.Name == "Type" {
//drill down to interface type
s := t.Decl.Specs[0].(*ast.TypeSpec).Type.(*ast.InterfaceType)
for _, m := range s.Methods.List {
acc = append(acc, "Type."+m.Names[0].Name)
}
}
acc = values(t.Consts, acc)
acc = values(t.Vars, acc)
acc = funcs(t.Funcs, "reflect.", acc)
acc = funcs(t.Methods, t.Name+".", acc)
}
return acc
}