parse_dir.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package parser
  2. import (
  3. "go/ast"
  4. "go/parser"
  5. "go/token"
  6. "io/fs"
  7. "os"
  8. go_path "path"
  9. "path/filepath"
  10. "strings"
  11. )
  12. func ParseDir(fset *token.FileSet, path string, filter func(fs.FileInfo) bool, mode parser.Mode) (pkgs map[string]*ast.Package, first error) {
  13. list, err := os.ReadDir(path)
  14. if err != nil {
  15. return nil, err
  16. }
  17. pkgs = make(map[string]*ast.Package)
  18. for _, d := range list {
  19. if d.IsDir() {
  20. var insidePkgs = make(map[string]*ast.Package)
  21. insidePkgs, first = ParseDir(fset, go_path.Join(path, d.Name()), filter, mode)
  22. if first != nil {
  23. return
  24. }
  25. for s, a2 := range insidePkgs {
  26. pkgs[s] = a2
  27. }
  28. }
  29. if !strings.HasSuffix(d.Name(), ".go") {
  30. continue
  31. }
  32. if filter != nil {
  33. info, err := d.Info()
  34. if err != nil {
  35. return nil, err
  36. }
  37. if !filter(info) {
  38. continue
  39. }
  40. }
  41. filename := filepath.Join(path, d.Name())
  42. if src, err := parser.ParseFile(fset, filename, nil, mode); err == nil {
  43. name := src.Name.Name
  44. pkg, found := pkgs[path]
  45. if !found {
  46. pkg = &ast.Package{
  47. Name: name,
  48. Files: make(map[string]*ast.File),
  49. }
  50. pkgs[path] = pkg
  51. }
  52. pkg.Files[filename] = src
  53. } else if first == nil {
  54. first = err
  55. }
  56. }
  57. return
  58. }