Commit a64b2699 authored by Robert Griesemer's avatar Robert Griesemer

godoc: documentation for all (not just exported) declarations

Removed the URL form parameter "f=text" in favor of a more
flexible mode parameter "m" which now accepts a list of mode
flags as documented in doc.go.

Fixes #1784.

R=rsc
CC=golang-dev
https://golang.org/cl/5227041
parent ba4fea93
...@@ -124,6 +124,17 @@ via regular expressions). The maximum number of full text search results shown ...@@ -124,6 +124,17 @@ via regular expressions). The maximum number of full text search results shown
can be set with the -maxresults flag; if set to 0, no full text results are can be set with the -maxresults flag; if set to 0, no full text results are
shown, and only an identifier index but no full text search index is created. shown, and only an identifier index but no full text search index is created.
The presentation mode of web pages served by godoc can be controlled with the
"m" URL parameter; it accepts a comma-separated list of flag names as value:
all show documentation for all (not just exported) declarations
src show the original source code rather then the extracted documentation
text present the page in textual (command-line) form rather than HTML
For instance, http://golang.org/pkg/big/?m=all,text shows the documentation for
all (not just the exported) declarations of package big, in textual form (as
it would appear when using godoc from the command line: "godoc -src big .*").
By default, godoc serves files from the file system of the underlying OS. By default, godoc serves files from the file system of the underlying OS.
Instead, a .zip file may be provided via the -zip flag, which contains Instead, a .zip file may be provided via the -zip flag, which contains
the file system to serve. The file paths stored in the .zip file must use the file system to serve. The file paths stored in the .zip file must use
...@@ -137,7 +148,6 @@ one may run godoc as follows: ...@@ -137,7 +148,6 @@ one may run godoc as follows:
godoc -http=:6060 -zip=go.zip -goroot=$HOME/go godoc -http=:6060 -zip=go.zip -goroot=$HOME/go
See "Godoc: documenting Go code" for how to write good comments for godoc: See "Godoc: documenting Go code" for how to write good comments for godoc:
http://blog.golang.org/2011/03/godoc-documenting-go-code.html http://blog.golang.org/2011/03/godoc-documenting-go-code.html
*/ */
......
...@@ -816,10 +816,30 @@ const builtinPkgPath = "builtin/" ...@@ -816,10 +816,30 @@ const builtinPkgPath = "builtin/"
type PageInfoMode uint type PageInfoMode uint
const ( const (
exportsOnly PageInfoMode = 1 << iota // only keep exported stuff noFiltering PageInfoMode = 1 << iota // do not filter exports
genDoc // generate documentation showSource // show source code, do not extract documentation
noHtml // show result in textual form, do not generate HTML
) )
// modeNames defines names for each PageInfoMode flag.
var modeNames = map[string]PageInfoMode{
"all": noFiltering,
"src": showSource,
"text": noHtml,
}
// getPageInfoMode computes the PageInfoMode flags by analyzing the request
// URL form value "m". It is value is a comma-separated list of mode names
// as defined by modeNames (e.g.: m=src,text).
func getPageInfoMode(r *http.Request) (mode PageInfoMode) {
for _, k := range strings.Split(r.FormValue("m"), ",") {
if m, found := modeNames[strings.TrimSpace(k)]; found {
mode |= m
}
}
return
}
type PageInfo struct { type PageInfo struct {
Dirname string // directory containing the package Dirname string // directory containing the package
PList []string // list of package names found PList []string // list of package names found
...@@ -878,6 +898,16 @@ func inList(name string, list []string) bool { ...@@ -878,6 +898,16 @@ func inList(name string, list []string) bool {
return false return false
} }
func stripFunctionBodies(pkg *ast.Package) {
for _, f := range pkg.Files {
for _, d := range f.Decls {
if f, ok := d.(*ast.FuncDecl); ok {
f.Body = nil
}
}
}
}
// getPageInfo returns the PageInfo for a package directory abspath. If the // getPageInfo returns the PageInfo for a package directory abspath. If the
// parameter genAST is set, an AST containing only the package exports is // parameter genAST is set, an AST containing only the package exports is
// computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc) // computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc)
...@@ -1003,10 +1033,11 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf ...@@ -1003,10 +1033,11 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
var past *ast.File var past *ast.File
var pdoc *doc.PackageDoc var pdoc *doc.PackageDoc
if pkg != nil { if pkg != nil {
if mode&exportsOnly != 0 { if mode&noFiltering == 0 {
ast.PackageExports(pkg) ast.PackageExports(pkg)
} }
if mode&genDoc != 0 { stripFunctionBodies(pkg)
if mode&showSource == 0 {
pdoc = doc.NewPackageDoc(pkg, path.Clean(relpath)) // no trailing '/' in importpath pdoc = doc.NewPackageDoc(pkg, path.Clean(relpath)) // no trailing '/' in importpath
} else { } else {
past = ast.MergePackageFiles(pkg, ast.FilterUnassociatedComments) past = ast.MergePackageFiles(pkg, ast.FilterUnassociatedComments)
...@@ -1065,12 +1096,9 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ...@@ -1065,12 +1096,9 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
relpath := r.URL.Path[len(h.pattern):] relpath := r.URL.Path[len(h.pattern):]
abspath := absolutePath(relpath, h.fsRoot) abspath := absolutePath(relpath, h.fsRoot)
var mode PageInfoMode mode := getPageInfoMode(r)
if relpath != builtinPkgPath { if relpath == builtinPkgPath {
mode = exportsOnly mode = noFiltering
}
if r.FormValue("m") != "src" {
mode |= genDoc
} }
info := h.getPageInfo(abspath, relpath, r.FormValue("p"), mode) info := h.getPageInfo(abspath, relpath, r.FormValue("p"), mode)
if info.Err != nil { if info.Err != nil {
...@@ -1079,7 +1107,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ...@@ -1079,7 +1107,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
if r.FormValue("f") == "text" { if mode&noHtml != 0 {
contents := applyTemplate(packageText, "packageText", info) contents := applyTemplate(packageText, "packageText", info)
serveText(w, contents) serveText(w, contents)
return return
...@@ -1184,7 +1212,7 @@ func search(w http.ResponseWriter, r *http.Request) { ...@@ -1184,7 +1212,7 @@ func search(w http.ResponseWriter, r *http.Request) {
query := strings.TrimSpace(r.FormValue("q")) query := strings.TrimSpace(r.FormValue("q"))
result := lookup(query) result := lookup(query)
if r.FormValue("f") == "text" { if getPageInfoMode(r)&noHtml != 0 {
contents := applyTemplate(searchText, "searchText", result) contents := applyTemplate(searchText, "searchText", result)
serveText(w, contents) serveText(w, contents)
return return
......
...@@ -389,11 +389,10 @@ func main() { ...@@ -389,11 +389,10 @@ func main() {
var mode PageInfoMode var mode PageInfoMode
if *srcMode { if *srcMode {
// only filter exports if we don't have explicit command-line filter arguments // only filter exports if we don't have explicit command-line filter arguments
if flag.NArg() == 1 { if flag.NArg() > 1 {
mode |= exportsOnly mode |= noFiltering
} }
} else { mode |= showSource
mode = exportsOnly | genDoc
} }
// TODO(gri): Provide a mechanism (flag?) to select a package // TODO(gri): Provide a mechanism (flag?) to select a package
// if there are multiple packages in a directory. // if there are multiple packages in a directory.
......
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