...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package main
17
18 import (
19 "flag"
20 "fmt"
21 "go/ast"
22 "log"
23 "os"
24
25 "golang.org/x/tools/go/cfg"
26 "golang.org/x/tools/go/packages"
27 )
28
29 func main() {
30 flag.Parse()
31 if len(flag.Args()) != 2 {
32 log.Fatal("Usage: package funcname")
33 }
34 pattern, funcname := flag.Args()[0], flag.Args()[1]
35 pkgs, err := packages.Load(&packages.Config{Mode: packages.LoadSyntax}, pattern)
36 if err != nil {
37 log.Fatal(err)
38 }
39 if packages.PrintErrors(pkgs) > 0 {
40 os.Exit(1)
41 }
42 for _, pkg := range pkgs {
43 for _, f := range pkg.Syntax {
44 for _, decl := range f.Decls {
45 if decl, ok := decl.(*ast.FuncDecl); ok {
46 if decl.Name.Name == funcname {
47 g := cfg.New(decl.Body, mayReturn)
48 fmt.Println(g.Dot(pkg.Fset))
49 os.Exit(0)
50 }
51 }
52 }
53 }
54 }
55 log.Fatalf("no function %q found in %s", funcname, pattern)
56 }
57
58
59 func mayReturn(call *ast.CallExpr) bool {
60 switch fun := call.Fun.(type) {
61 case *ast.Ident:
62 return fun.Name != "panic"
63 case *ast.SelectorExpr:
64 return fun.Sel.Name != "Fatal"
65 }
66 return true
67 }
68
View as plain text