Source file
src/go/doc/headscan.go
1
2
3
4
5
6
7
16 package main
17
18 import (
19 "flag"
20 "fmt"
21 "go/doc"
22 "go/parser"
23 "go/token"
24 "io/fs"
25 "os"
26 "path/filepath"
27 "regexp"
28 "runtime"
29 "strings"
30 )
31
32 var (
33 root = flag.String("root", filepath.Join(runtime.GOROOT(), "src"), "root of filesystem tree to scan")
34 verbose = flag.Bool("v", false, "verbose mode")
35 )
36
37
38 var html_h = regexp.MustCompile(`<h3 id="[^"]*">`)
39
40 const html_endh = "</h3>\n"
41
42 func isGoFile(fi fs.FileInfo) bool {
43 return strings.HasSuffix(fi.Name(), ".go") &&
44 !strings.HasSuffix(fi.Name(), "_test.go")
45 }
46
47 func appendHeadings(list []string, comment string) []string {
48 var buf strings.Builder
49 doc.ToHTML(&buf, comment, nil)
50 for s := buf.String(); s != ""; {
51 loc := html_h.FindStringIndex(s)
52 if len(loc) == 0 {
53 break
54 }
55 var inner string
56 inner, s, _ = strings.Cut(s[loc[1]:], html_endh)
57 list = append(list, inner)
58 }
59 return list
60 }
61
62 func main() {
63 flag.Parse()
64 fset := token.NewFileSet()
65 nheadings := 0
66 err := filepath.WalkDir(*root, func(path string, info fs.DirEntry, err error) error {
67 if !info.IsDir() {
68 return nil
69 }
70 pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments)
71 if err != nil {
72 if *verbose {
73 fmt.Fprintln(os.Stderr, err)
74 }
75 return nil
76 }
77 for _, pkg := range pkgs {
78 d := doc.New(pkg, path, doc.Mode(0))
79 list := appendHeadings(nil, d.Doc)
80 for _, d := range d.Consts {
81 list = appendHeadings(list, d.Doc)
82 }
83 for _, d := range d.Types {
84 list = appendHeadings(list, d.Doc)
85 }
86 for _, d := range d.Vars {
87 list = appendHeadings(list, d.Doc)
88 }
89 for _, d := range d.Funcs {
90 list = appendHeadings(list, d.Doc)
91 }
92 if len(list) > 0 {
93
94
95 fmt.Printf("%s (package %s)\n", path, pkg.Name)
96 for _, h := range list {
97 fmt.Printf("\t%s\n", h)
98 }
99 nheadings += len(list)
100 }
101 }
102 return nil
103 })
104 if err != nil {
105 fmt.Fprintln(os.Stderr, err)
106 os.Exit(1)
107 }
108 fmt.Println(nheadings, "headings found")
109 }
110
View as plain text