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
|
// 24 may 2014
package main
import (
"fmt"
"os"
"strings"
"go/token"
"go/ast"
"go/parser"
)
func main() {
var pkg *ast.Package
importpath := os.Args[1]
fileset := token.NewFileSet()
filter := func(i os.FileInfo) bool {
return strings.HasSuffix(i.Name(), "_windows.go")
}
pkgs, err := parser.ParseDir(fileset, importpath,
filter, parser.AllErrors)
if err != nil {
panic(err)
}
if len(pkgs) != 1 {
panic("more than one package found")
}
for k, _ := range pkgs { // get the sole key
pkg = pkgs[k]
}
var run func(...ast.Decl)
var runstmt func(ast.Stmt)
var runblock func(*ast.BlockStmt)
desired := func(name string) bool {
return strings.HasPrefix(name, "_")
}
run = func(decls ...ast.Decl) {
for _, d := range decls {
switch dd := d.(type) {
case *ast.FuncDecl:
runblock(dd.Body)
case *ast.GenDecl:
if desired(d.Name.String()) {
fmt.Println(d.Name.String())
}
default:
panic(fmt.Errorf("unknown decl type %T: %v", dd, dd))
}
}
}
runstmt = func(s ast.Stmt) {
switch ss := s.(type) {
case *ast.DeclStmt:
run(ss.Decl)
case *ast.LabeledStmt:
runstmt(ss.Stmt)
case *ast.AssignStmt:
// TODO go through Lhs if ss.Tok type == DEFINE
case *ast.GoStmt:
// these don't have decls
case *ast.EmptyStmt:
case *ast.ExprStmt:
case *ast.SendStmt:
case *ast.IncDecStmt:
// all do nothing
default:
panic(fmt.Errorf("unknown stmt type %T: %v", dd, dd))
}
}
runblock = func(block *ast.BlockStmt) {
for _, s := range block.Stmt {
runstmt(s)
}
}
for _, f := range pkg.Files {
run(f.Decls...)
}
}
|