From faa8a71ab532725a7fd9d901a97f74c5038c409b Mon Sep 17 00:00:00 2001 From: Mostyn Bramley-Moore Date: Thu, 26 Jul 2018 20:37:57 +0000 Subject: [PATCH] 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 --- godoc/godoc.go | 18 ++++++++++++++++++ godoc/godoc_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/godoc/godoc.go b/godoc/godoc.go index f191a9d9..0acb49bf 100644 --- a/godoc/godoc.go +++ b/godoc/godoc.go @@ -666,6 +666,7 @@ func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) string play := "" if eg.Play != nil && p.ShowPlayground { var buf bytes.Buffer + eg.Play.Comments = filterOutBuildAnnotations(eg.Play.Comments) if err := format.Node(&buf, info.FSet, eg.Play); err != nil { log.Print(err) } else { @@ -694,6 +695,23 @@ func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) 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 // name. For example, "Foo_Bar_quux" becomes "Foo.Bar (Quux)". func (p *Presentation) example_nameFunc(s string) string { diff --git a/godoc/godoc_test.go b/godoc/godoc_test.go index c1d631c1..3c21849f 100644 --- a/godoc/godoc_test.go +++ b/godoc/godoc_test.go @@ -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") + } +}