Commit f1a9f1df authored by Yury Smolsky's avatar Yury Smolsky Committed by Robert Griesemer

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: default avatarRobert Griesemer <gri@golang.org>
parent a540aa33
...@@ -219,6 +219,18 @@ func playExample(file *ast.File, f *ast.FuncDecl) *ast.File { ...@@ -219,6 +219,18 @@ func playExample(file *ast.File, f *ast.FuncDecl) *ast.File {
for i := 0; i < len(depDecls); i++ { for i := 0; i < len(depDecls); i++ {
switch d := depDecls[i].(type) { switch d := depDecls[i].(type) {
case *ast.FuncDecl: 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) ast.Inspect(d.Body, inspectFunc)
case *ast.GenDecl: case *ast.GenDecl:
for _, spec := range d.Specs { for _, spec := range d.Specs {
......
...@@ -351,6 +351,68 @@ func TestExamplesWholeFile(t *testing.T) { ...@@ -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 { func formatFile(t *testing.T, fset *token.FileSet, n *ast.File) string {
if n == nil { if n == nil {
return "<nil>" return "<nil>"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment