main.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package main
  2. import (
  3. "encoding/json"
  4. "go/ast"
  5. "go/parser"
  6. "go/token"
  7. "io/fs"
  8. "log"
  9. "os"
  10. "path"
  11. "path/filepath"
  12. "sort"
  13. "strings"
  14. )
  15. func main() {
  16. results := Functions{}
  17. // Parse
  18. filepath.Walk("./kubernetes", func(file string, info fs.FileInfo, err error) error {
  19. if err != nil {
  20. return err
  21. }
  22. if info.IsDir() {
  23. return nil
  24. }
  25. if path.Ext(file) != ".go" {
  26. return nil
  27. }
  28. for _, s := range []string{
  29. "fake", // test code
  30. "test", // test code
  31. "zz_generated", // generated code
  32. "generated", // generated code
  33. "api.pb.go", // generated code
  34. "vendor", // external libs
  35. "third_party", // external libs
  36. "sample", // example code
  37. "example",
  38. } {
  39. if strings.Contains(file, s) {
  40. return nil
  41. }
  42. }
  43. results = append(results, parseSrc(file)...)
  44. return nil
  45. })
  46. // Sort
  47. sort.Sort(results)
  48. // Print
  49. repoId := 1 /* id of the kubernetes/kubernetes@v1.27.4 */
  50. id := repoId * 100_000_000
  51. for _, f := range results {
  52. f.ID = uint64(id)
  53. id += 1
  54. json.NewEncoder(os.Stdout).Encode(f)
  55. }
  56. }
  57. func parseSrc(filename string) []Function {
  58. s, err := os.ReadFile(filename)
  59. if err != nil {
  60. panic(err) // there will be no err
  61. }
  62. lines := strings.Split(string(s), "\n")
  63. f := []Function{}
  64. fset := token.NewFileSet()
  65. node, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
  66. if err != nil {
  67. log.Fatalf("Error parsing file: %v", err)
  68. }
  69. for _, decl := range node.Decls {
  70. switch d := decl.(type) {
  71. case *ast.FuncDecl:
  72. start := fset.Position(d.Pos()).Line
  73. if d.Doc != nil {
  74. start = fset.Position(d.Doc.Pos()).Line
  75. }
  76. end := fset.Position(d.End()).Line
  77. signature_pos := fset.Position(d.Name.Pos()).Line
  78. signature, _ := strings.CutSuffix(lines[signature_pos-1], " {")
  79. f = append(f, Function{
  80. Name: d.Name.Name,
  81. Signature: signature,
  82. Line: FunctionPos{
  83. From: start,
  84. To: end,
  85. },
  86. File: filename[11:],
  87. Code: strings.Join(lines[start-1:end], "\n"),
  88. })
  89. }
  90. }
  91. return f
  92. }