go/doc: inspect function signature for building playground examples

This documentation example was broken:
https://golang.org/pkg/image/png/#example_Decode.
It did not have the "io" package imported,
The package was referenced in the result type of the function.

The "playExample" function did not inspect
the result types of declared functions.

This CL adds inspecting of parameters and result types of functions.

Fixes #28492
Updates #9679

Change-Id: I6d8b11bad2db8ea8ba69039cfaa914093bdd5132
Reviewed-on: https://go-review.googlesource.com/c/146118
Run-TryBot: Yury Smolsky <yury@smolsky.by>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Yury Smolsky 2018-10-31 00:19:35 +02:00 committed by Robert Griesemer
parent a540aa338a
commit f1a9f1df50
2 changed files with 74 additions and 0 deletions

View File

@ -219,6 +219,18 @@ func playExample(file *ast.File, f *ast.FuncDecl) *ast.File {
for i := 0; i < len(depDecls); i++ {
switch d := depDecls[i].(type) {
case *ast.FuncDecl:
// Inspect types of parameters and results. See #28492.
if d.Type.Params != nil {
for _, p := range d.Type.Params.List {
ast.Inspect(p.Type, inspectFunc)
}
}
if d.Type.Results != nil {
for _, r := range d.Type.Results.List {
ast.Inspect(r.Type, inspectFunc)
}
}
ast.Inspect(d.Body, inspectFunc)
case *ast.GenDecl:
for _, spec := range d.Specs {

View File

@ -351,6 +351,68 @@ func TestExamplesWholeFile(t *testing.T) {
}
}
const exampleInspectSignature = `package foo_test
import (
"bytes"
"io"
)
func getReader() io.Reader { return nil }
func do(b bytes.Reader) {}
func Example() {
getReader()
do()
// Output:
}
func ExampleIgnored() {
}
`
const exampleInspectSignatureOutput = `package main
import (
"bytes"
"io"
)
func getReader() io.Reader { return nil }
func do(b bytes.Reader) {}
func main() {
getReader()
do()
}
`
func TestExampleInspectSignature(t *testing.T) {
// Verify that "bytes" and "io" are imported. See issue #28492.
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleInspectSignature), parser.ParseComments)
if err != nil {
t.Fatal(err)
}
es := doc.Examples(file)
if len(es) != 2 {
t.Fatalf("wrong number of examples; got %d want 2", len(es))
}
// We are interested in the first example only.
e := es[0]
if e.Name != "" {
t.Errorf("got Name == %q, want %q", e.Name, "")
}
if g, w := formatFile(t, fset, e.Play), exampleInspectSignatureOutput; g != w {
t.Errorf("got Play == %q, want %q", g, w)
}
if g, w := e.Output, ""; g != w {
t.Errorf("got Output == %q, want %q", g, w)
}
}
func formatFile(t *testing.T, fset *token.FileSet, n *ast.File) string {
if n == nil {
return "<nil>"