Skip to content

Commit 766a706

Browse files
committed
godoc: add a Corpus hook to summarize a package
This lets godoc implementations provide a more efficient means of getting this information, without reading files and parsing the package docs. This is especially important when the files themselves don't actually exist and the VFS is synthesizing them on demand (e.g. protocol buffer files -> their generated *.pb.go files). This means corpus.Init can run quickly, without generating every protocol file in a large corpus (or fetching it from a cache). In the future, this hook could also be used for caching the summaries of regular packages. R=golang-dev, adg CC=golang-dev https://golang.org/cl/19440043
1 parent 99890b8 commit 766a706

File tree

2 files changed

+48
-24
lines changed

2 files changed

+48
-24
lines changed

godoc/corpus.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ type Corpus struct {
3838
// The default is 1000.
3939
MaxResults int
4040

41+
// SummarizePackage optionally specifies a function to
42+
// summarize a package. It exists as an optimization to
43+
// avoid reading files to parse package comments.
44+
//
45+
// If SummarizePackage returns false for ok, the caller
46+
// ignores all return values and parses the files in the package
47+
// as if SummarizePackage were nil.
48+
//
49+
// If showList is false, the package is hidden from the
50+
// package listing.
51+
SummarizePackage func(pkg string) (summary string, showList, ok bool)
52+
4153
testDir string // TODO(bradfitz,adg): migrate old godoc flag? looks unused.
4254

4355
// Send a value on this channel to trigger a metadata refresh.

godoc/dirtrees.go

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,26 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i
7070
}
7171
}
7272

73+
var synopses [3]string // prioritized package documentation (0 == highest priority)
74+
75+
show := true // show in package listing
76+
hasPkgFiles := false
77+
haveSummary := false
78+
79+
if hook := b.c.SummarizePackage; hook != nil {
80+
if summary, show0, ok := hook(strings.TrimPrefix(path, "/src/pkg/")); ok {
81+
hasPkgFiles = true
82+
show = show0
83+
synopses[0] = summary
84+
haveSummary = true
85+
}
86+
}
87+
7388
list, _ := b.c.fs.ReadDir(path)
7489

7590
// determine number of subdirectories and if there are package files
76-
hasPkgFiles := false
7791
var dirchs []chan *Directory
7892

79-
var synopses [3]string // prioritized package documentation (0 == highest priority)
8093
for _, d := range list {
8194
switch {
8295
case isPkgDir(d):
@@ -86,32 +99,31 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i
8699
name := d.Name()
87100
ch <- b.newDirTree(fset, pathpkg.Join(path, name), name, depth+1)
88101
}(d)
89-
case isPkgFile(d):
102+
case !haveSummary && isPkgFile(d):
90103
// looks like a package file, but may just be a file ending in ".go";
91104
// don't just count it yet (otherwise we may end up with hasPkgFiles even
92105
// though the directory doesn't contain any real package files - was bug)
93-
if synopses[0] == "" {
94-
// no "optimal" package synopsis yet; continue to collect synopses
95-
file, err := b.c.parseFile(fset, pathpkg.Join(path, d.Name()),
96-
parser.ParseComments|parser.PackageClauseOnly)
97-
if err == nil {
98-
hasPkgFiles = true
99-
if file.Doc != nil {
100-
// prioritize documentation
101-
i := -1
102-
switch file.Name.Name {
103-
case name:
104-
i = 0 // normal case: directory name matches package name
105-
case "main":
106-
i = 1 // directory contains a main package
107-
default:
108-
i = 2 // none of the above
109-
}
110-
if 0 <= i && i < len(synopses) && synopses[i] == "" {
111-
synopses[i] = doc.Synopsis(file.Doc.Text())
112-
}
106+
// no "optimal" package synopsis yet; continue to collect synopses
107+
file, err := b.c.parseFile(fset, pathpkg.Join(path, d.Name()),
108+
parser.ParseComments|parser.PackageClauseOnly)
109+
if err == nil {
110+
hasPkgFiles = true
111+
if file.Doc != nil {
112+
// prioritize documentation
113+
i := -1
114+
switch file.Name.Name {
115+
case name:
116+
i = 0 // normal case: directory name matches package name
117+
case "main":
118+
i = 1 // directory contains a main package
119+
default:
120+
i = 2 // none of the above
121+
}
122+
if 0 <= i && i < len(synopses) && synopses[i] == "" {
123+
synopses[i] = doc.Synopsis(file.Doc.Text())
113124
}
114125
}
126+
haveSummary = synopses[0] != ""
115127
}
116128
}
117129
}
@@ -142,7 +154,7 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i
142154
Depth: depth,
143155
Path: path,
144156
Name: name,
145-
HasPkg: hasPkgFiles,
157+
HasPkg: hasPkgFiles && show, // TODO(bradfitz): add proper Hide field?
146158
Synopsis: synopsis,
147159
Dirs: dirs,
148160
}

0 commit comments

Comments
 (0)