Commit e11632ee authored by Andrew Gerrand's avatar Andrew Gerrand

go/doc, godoc: regard lone examples as "whole file" examples

Fixes #2930.

R=r, gri, rsc
CC=golang-dev
https://golang.org/cl/5657048
parent 1c987a32
...@@ -187,6 +187,10 @@ Here is an example of an example: ...@@ -187,6 +187,10 @@ Here is an example of an example:
Println("The output of this example function.") Println("The output of this example function.")
} }
The entire test file is presented as the example when it contains a single
example function, at least one other function, type, variable, or constant
declaration, and no test or benchmark functions.
See the documentation of the testing package for more information. See the documentation of the testing package for more information.
`, `,
} }
......
...@@ -516,10 +516,13 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File ...@@ -516,10 +516,13 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File
continue continue
} }
// print code, unindent and remove surrounding braces // print code
code := node_htmlFunc(eg.Body, fset) code := node_htmlFunc(eg.Body, fset)
code = strings.Replace(code, "\n ", "\n", -1) if len(code) > 0 && code[0] == '{' {
code = code[2 : len(code)-2] // unindent and remove surrounding braces
code = strings.Replace(code, "\n ", "\n", -1)
code = code[2 : len(code)-2]
}
err := exampleHTML.Execute(&buf, struct { err := exampleHTML.Execute(&buf, struct {
Name, Code, Output string Name, Code, Output string
......
...@@ -9,6 +9,7 @@ package doc ...@@ -9,6 +9,7 @@ package doc
import ( import (
"go/ast" "go/ast"
"go/printer" "go/printer"
"go/token"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
...@@ -21,28 +22,47 @@ type Example struct { ...@@ -21,28 +22,47 @@ type Example struct {
} }
func Examples(pkg *ast.Package) []*Example { func Examples(pkg *ast.Package) []*Example {
var examples []*Example var list []*Example
for _, src := range pkg.Files { for _, file := range pkg.Files {
for _, decl := range src.Decls { hasTests := false // file contains tests or benchmarks
numDecl := 0 // number of non-import declarations in the file
var flist []*Example
for _, decl := range file.Decls {
if g, ok := decl.(*ast.GenDecl); ok && g.Tok != token.IMPORT {
numDecl++
continue
}
f, ok := decl.(*ast.FuncDecl) f, ok := decl.(*ast.FuncDecl)
if !ok { if !ok {
continue continue
} }
numDecl++
name := f.Name.Name name := f.Name.Name
if isTest(name, "Test") || isTest(name, "Benchmark") {
hasTests = true
continue
}
if !isTest(name, "Example") { if !isTest(name, "Example") {
continue continue
} }
examples = append(examples, &Example{ flist = append(flist, &Example{
Name: name[len("Example"):], Name: name[len("Example"):],
Body: &printer.CommentedNode{ Body: &printer.CommentedNode{
Node: f.Body, Node: f.Body,
Comments: src.Comments, Comments: file.Comments,
}, },
Output: f.Doc.Text(), Output: f.Doc.Text(),
}) })
} }
if !hasTests && numDecl > 1 && len(flist) == 1 {
// If this file only has one example function, some
// other top-level declarations, and no tests or
// benchmarks, use the whole file as the example.
flist[0].Body.Node = file
}
list = append(list, flist...)
} }
return examples return list
} }
// isTest tells whether name looks like a test, example, or benchmark. // isTest tells whether name looks like a test, example, or benchmark.
......
...@@ -64,6 +64,9 @@ ...@@ -64,6 +64,9 @@
// func ExampleT_suffix() { ... } // func ExampleT_suffix() { ... }
// func ExampleT_M_suffix() { ... } // func ExampleT_M_suffix() { ... }
// //
// The entire test file is presented as the example when it contains a single
// example function, at least one other function, type, variable, or constant
// declaration, and no test or benchmark functions.
package testing package testing
import ( import (
......
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