godoc: skip build tag annotations when displaying examples

After moving the filepath.Walk example to a standalone example file
in CL 122237 (so it could use a standalone function), godoc includes
the build tag annotation ("// +build !windows,!plan9" in this case)
in the runnable example.  The example runs correctly, but the
annotation might be confusing for new users.

With this change, godoc skips these annotations when displaying examples.

Fixes golang/go#26490.

Change-Id: Ice3d6a2ce4db5b5176c9c6fcabc01b69c323016d
GitHub-Last-Rev: 52beabd3d2a9cb9a556bfa3bd998a2e31ac96960
GitHub-Pull-Request: golang/tools#40
Reviewed-on: https://go-review.googlesource.com/125040
Reviewed-by: Andrew Bonventre <andybons@golang.org>
This commit is contained in:
Mostyn Bramley-Moore 2018-07-26 20:37:57 +00:00 committed by Andrew Bonventre
parent 0bf5a32247
commit faa8a71ab5
2 changed files with 63 additions and 0 deletions

View File

@ -666,6 +666,7 @@ func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) string
play := "" play := ""
if eg.Play != nil && p.ShowPlayground { if eg.Play != nil && p.ShowPlayground {
var buf bytes.Buffer var buf bytes.Buffer
eg.Play.Comments = filterOutBuildAnnotations(eg.Play.Comments)
if err := format.Node(&buf, info.FSet, eg.Play); err != nil { if err := format.Node(&buf, info.FSet, eg.Play); err != nil {
log.Print(err) log.Print(err)
} else { } else {
@ -694,6 +695,23 @@ func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) string
return buf.String() return buf.String()
} }
func filterOutBuildAnnotations(cg []*ast.CommentGroup) []*ast.CommentGroup {
if len(cg) == 0 {
return cg
}
for i := range cg {
if !strings.HasPrefix(cg[i].Text(), "+build ") {
// Found the first non-build tag, return from here until the end
// of the slice.
return cg[i:]
}
}
// There weren't any non-build tags, return an empty slice.
return []*ast.CommentGroup{}
}
// example_nameFunc takes an example function name and returns its display // example_nameFunc takes an example function name and returns its display
// name. For example, "Foo_Bar_quux" becomes "Foo.Bar (Quux)". // name. For example, "Foo_Bar_quux" becomes "Foo.Bar (Quux)".
func (p *Presentation) example_nameFunc(s string) string { func (p *Presentation) example_nameFunc(s string) string {

View File

@ -321,3 +321,48 @@ func TestSrcToPkgLinkFunc(t *testing.T) {
} }
} }
} }
func TestFilterOutBuildAnnotations(t *testing.T) {
src := []byte(`
// +build !foo
// +build !anothertag
// non-tag comment
package foo
func bar() int {
return 42
}`)
fset := token.NewFileSet()
af, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments)
if err != nil {
t.Fatal(err)
}
var found bool
for _, cg := range af.Comments {
if strings.HasPrefix(cg.Text(), "+build ") {
found = true
break
}
}
if !found {
t.Errorf("TestFilterOutBuildAnnotations is broken: missing build tag in test input")
}
found = false
for _, cg := range filterOutBuildAnnotations(af.Comments) {
if strings.HasPrefix(cg.Text(), "+build ") {
t.Errorf("filterOutBuildAnnotations failed to filter build tag")
}
if strings.Contains(cg.Text(), "non-tag comment") {
found = true
}
}
if !found {
t.Errorf("filterOutBuildAnnotations should not remove non-build tag comment")
}
}