Advertisement
Guest User

Untitled

a guest
Feb 19th, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.90 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "go/ast"
  6. "go/parser"
  7. "go/token"
  8. "io/ioutil"
  9. "os"
  10. "os/exec"
  11. "path/filepath"
  12. "strings"
  13. )
  14.  
  15. func loadFuncDeclsM(out map[string]map[string]*ast.FuncDecl, f *ast.File) {
  16. if _, ok := out[f.Name.Name]; !ok {
  17. out[f.Name.Name] = make(map[string]*ast.FuncDecl)
  18. }
  19.  
  20. for _, decl := range f.Decls {
  21. if v, ok := decl.(*ast.FuncDecl); ok {
  22. out[f.Name.Name][v.Name.Name] = v
  23. }
  24. }
  25. }
  26.  
  27. func parse(fpath string) (*token.FileSet, map[string]map[string]*ast.FuncDecl) {
  28. fset := token.NewFileSet()
  29. b, err := ioutil.ReadFile(fpath)
  30. if err != nil {
  31. panic(err)
  32. }
  33. f, err := parser.ParseFile(fset, fpath, string(b), parser.ParseComments)
  34. if err != nil {
  35. panic(err)
  36. }
  37.  
  38. m := make(map[string]map[string]*ast.FuncDecl)
  39.  
  40. loadFuncDeclsM(m, f)
  41.  
  42. paths := getSrcPaths()
  43. findPackage := func(pkgname string) (string, error) {
  44. for _, p := range paths {
  45. pkgpath := filepath.Join(p, pkgname)
  46. if _, err := os.Stat(pkgpath); err == nil {
  47. return pkgpath, nil
  48. }
  49. }
  50. return "", fmt.Errorf("could not find pkg: %s", pkgname)
  51. }
  52.  
  53. for _, i := range f.Imports {
  54. p, err := findPackage(strings.Trim(i.Path.Value, "\""))
  55. if err != nil {
  56. fmt.Fprintf(os.Stderr, "error: %v\n", err)
  57. continue
  58. }
  59. pkgs, err := parser.ParseDir(fset, p, func(fi os.FileInfo) bool { return true }, parser.ParseComments)
  60. if err != nil {
  61. fmt.Fprintf(os.Stderr, "error: %v\n", err)
  62. continue
  63. }
  64. for _, pkg := range pkgs {
  65. for _, f := range pkg.Files {
  66. loadFuncDeclsM(m, f)
  67. }
  68. }
  69. }
  70.  
  71. return fset, m
  72. }
  73.  
  74. func getSrcPath(name string) string {
  75. cmd := exec.Command("go", "env", name)
  76. b, err := cmd.Output()
  77. if err != nil {
  78. panic(err)
  79. }
  80. return filepath.Join(strings.Trim(string(b), "\r\n"), "src")
  81. }
  82.  
  83. func getSrcPaths() []string {
  84. return []string{getSrcPath("GOROOT"), getSrcPath("GOPATH")}
  85. }
  86.  
  87. func main() {
  88. fset, m := parse("main.go")
  89. results := m["exec"]["Command"].Type.Results.List
  90. ast.Print(fset, results)
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement