Commit 12cf2ff0 authored by Robert Griesemer's avatar Robert Griesemer

godoc: pass *PageInfos instead of *token.FileSets in templates

- convert all formatters that require a *token.FileSet to
  consistenly use a *PageInfo as first argument instead
- adjust templates correspondingly
- fix outstanding bug from previous CL 8005044

Going forward, with this change the affected functions have
access to the full page "context" (PageInfo), not just the
respective file set. This will permit better context-dependent
formatting in the future.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/7860049
parent 50231fa1
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
{{comment_html .Doc}} {{comment_html .Doc}}
</div> </div>
</div> </div>
{{example_html "" $.Examples $.FSet}} {{example_html $ ""}}
<div id="pkg-index" class="toggleVisible"> <div id="pkg-index" class="toggleVisible">
<div class="collapsed"> <div class="collapsed">
...@@ -60,18 +60,18 @@ ...@@ -60,18 +60,18 @@
{{end}} {{end}}
{{range .Funcs}} {{range .Funcs}}
{{$name_html := html .Name}} {{$name_html := html .Name}}
<dd><a href="#{{$name_html}}">{{node_html .Decl $.FSet}}</a></dd> <dd><a href="#{{$name_html}}">{{node_html $ .Decl}}</a></dd>
{{end}} {{end}}
{{range .Types}} {{range .Types}}
{{$tname_html := html .Name}} {{$tname_html := html .Name}}
<dd><a href="#{{$tname_html}}">type {{$tname_html}}</a></dd> <dd><a href="#{{$tname_html}}">type {{$tname_html}}</a></dd>
{{range .Funcs}} {{range .Funcs}}
{{$name_html := html .Name}} {{$name_html := html .Name}}
<dd>&nbsp; &nbsp; <a href="#{{$name_html}}">{{node_html .Decl $.FSet}}</a></dd> <dd>&nbsp; &nbsp; <a href="#{{$name_html}}">{{node_html $ .Decl}}</a></dd>
{{end}} {{end}}
{{range .Methods}} {{range .Methods}}
{{$name_html := html .Name}} {{$name_html := html .Name}}
<dd>&nbsp; &nbsp; <a href="#{{$tname_html}}.{{$name_html}}">{{node_html .Decl $.FSet}}</a></dd> <dd>&nbsp; &nbsp; <a href="#{{$tname_html}}.{{$name_html}}">{{node_html $ .Decl}}</a></dd>
{{end}} {{end}}
{{end}} {{end}}
{{if $.Notes}} {{if $.Notes}}
...@@ -109,59 +109,59 @@ ...@@ -109,59 +109,59 @@
{{with .Consts}} {{with .Consts}}
<h2 id="pkg-constants">Constants</h2> <h2 id="pkg-constants">Constants</h2>
{{range .}} {{range .}}
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{end}} {{end}}
{{end}} {{end}}
{{with .Vars}} {{with .Vars}}
<h2 id="pkg-variables">Variables</h2> <h2 id="pkg-variables">Variables</h2>
{{range .}} {{range .}}
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{end}} {{end}}
{{end}} {{end}}
{{range .Funcs}} {{range .Funcs}}
{{/* Name is a string - no need for FSet */}} {{/* Name is a string - no need for FSet */}}
{{$name_html := html .Name}} {{$name_html := html .Name}}
<h2 id="{{$name_html}}">func <a href="{{posLink_url .Decl $.FSet}}">{{$name_html}}</a></h2> <h2 id="{{$name_html}}">func <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a></h2>
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{example_html .Name $.Examples $.FSet}} {{example_html $ .Name}}
{{end}} {{end}}
{{range .Types}} {{range .Types}}
{{$tname := .Name}} {{$tname := .Name}}
{{$tname_html := html .Name}} {{$tname_html := html .Name}}
<h2 id="{{$tname_html}}">type <a href="{{posLink_url .Decl $.FSet}}">{{$tname_html}}</a></h2> <h2 id="{{$tname_html}}">type <a href="{{posLink_url $ .Decl}}">{{$tname_html}}</a></h2>
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{range .Consts}} {{range .Consts}}
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{end}} {{end}}
{{range .Vars}} {{range .Vars}}
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{end}} {{end}}
{{example_html $tname $.Examples $.FSet}} {{example_html $ $tname}}
{{range .Funcs}} {{range .Funcs}}
{{$name_html := html .Name}} {{$name_html := html .Name}}
<h3 id="{{$name_html}}">func <a href="{{posLink_url .Decl $.FSet}}">{{$name_html}}</a></h3> <h3 id="{{$name_html}}">func <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a></h3>
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{example_html .Name $.Examples $.FSet}} {{example_html $ .Name}}
{{end}} {{end}}
{{range .Methods}} {{range .Methods}}
{{$name_html := html .Name}} {{$name_html := html .Name}}
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url .Decl $.FSet}}">{{$name_html}}</a></h3> <h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a></h3>
<pre>{{node_html .Decl $.FSet}}</pre> <pre>{{node_html $ .Decl}}</pre>
{{comment_html .Doc}} {{comment_html .Doc}}
{{$name := printf "%s_%s" $tname .Name}} {{$name := printf "%s_%s" $tname .Name}}
{{example_html $name $.Examples $.FSet}} {{example_html $ $name}}
{{end}} {{end}}
{{end}} {{end}}
{{end}} {{end}}
...@@ -179,7 +179,7 @@ ...@@ -179,7 +179,7 @@
{{end}} {{end}}
{{with .PAst}} {{with .PAst}}
<pre>{{node_html . $.FSet}}</pre> <pre>{{node_html $ .}}</pre>
{{end}} {{end}}
{{with .Dirs}} {{with .Dirs}}
......
{{with .PAst}}{{node . $.FSet}}{{end}}{{/* {{with .PAst}}{{node $ .}}{{end}}{{/*
--------------------------------------- ---------------------------------------
...@@ -11,14 +11,14 @@ package {{.Name}} ...@@ -11,14 +11,14 @@ package {{.Name}}
import "{{.ImportPath}}" import "{{.ImportPath}}"
{{comment_text .Doc " " "\t"}} {{comment_text .Doc " " "\t"}}
{{example_text "" $.Examples $.FSet " "}}{{/* {{example_text $ "" " "}}{{/*
--------------------------------------- ---------------------------------------
*/}}{{with .Consts}} */}}{{with .Consts}}
CONSTANTS CONSTANTS
{{range .}}{{node .Decl $.FSet}} {{range .}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}}{{end}} {{comment_text .Doc " " "\t"}}{{end}}
{{end}}{{/* {{end}}{{/*
...@@ -27,7 +27,7 @@ CONSTANTS ...@@ -27,7 +27,7 @@ CONSTANTS
*/}}{{with .Vars}} */}}{{with .Vars}}
VARIABLES VARIABLES
{{range .}}{{node .Decl $.FSet}} {{range .}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}}{{end}} {{comment_text .Doc " " "\t"}}{{end}}
{{end}}{{/* {{end}}{{/*
...@@ -36,9 +36,9 @@ VARIABLES ...@@ -36,9 +36,9 @@ VARIABLES
*/}}{{with .Funcs}} */}}{{with .Funcs}}
FUNCTIONS FUNCTIONS
{{range .}}{{node .Decl $.FSet}} {{range .}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}} {{comment_text .Doc " " "\t"}}
{{example_text .Name $.Examples $.FSet " "}} {{example_text $ .Name " "}}
{{end}}{{end}}{{/* {{end}}{{end}}{{/*
--------------------------------------- ---------------------------------------
...@@ -46,19 +46,19 @@ FUNCTIONS ...@@ -46,19 +46,19 @@ FUNCTIONS
*/}}{{with .Types}} */}}{{with .Types}}
TYPES TYPES
{{range .}}{{$tname := .Name}}{{node .Decl $.FSet}} {{range .}}{{$tname := .Name}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}} {{comment_text .Doc " " "\t"}}
{{range .Consts}}{{node .Decl $.FSet}} {{range .Consts}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}} {{comment_text .Doc " " "\t"}}
{{end}}{{range .Vars}}{{node .Decl $.FSet}} {{end}}{{range .Vars}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}} {{comment_text .Doc " " "\t"}}
{{end}}{{example_text .Name $.Examples $.FSet " "}} {{end}}{{example_text $ .Name " "}}
{{range .Funcs}}{{node .Decl $.FSet}} {{range .Funcs}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}} {{comment_text .Doc " " "\t"}}
{{example_text .Name $.Examples $.FSet " "}} {{example_text $ .Name " "}}
{{end}}{{range .Methods}}{{node .Decl $.FSet}} {{end}}{{range .Methods}}{{node $ .Decl}}
{{comment_text .Doc " " "\t"}} {{comment_text .Doc " " "\t"}}
{{$name := printf "%s_%s" $tname .Name}}{{example_text $name $.Examples $.FSet " "}} {{$name := printf "%s_%s" $tname .Name}}{{example_text $ $name " "}}
{{end}}{{end}}{{end}}{{end}}{{/* {{end}}{{end}}{{end}}{{end}}{{/*
--------------------------------------- ---------------------------------------
......
...@@ -273,25 +273,20 @@ func infoSnippet_htmlFunc(info SpotInfo) string { ...@@ -273,25 +273,20 @@ func infoSnippet_htmlFunc(info SpotInfo) string {
return `<span class="alert">no snippet text available</span>` return `<span class="alert">no snippet text available</span>`
} }
func nodeFunc(node interface{}, fset *token.FileSet) string { func nodeFunc(info *PageInfo, node interface{}) string {
var buf bytes.Buffer var buf bytes.Buffer
writeNode(&buf, fset, node) writeNode(&buf, info.FSet, node)
return buf.String() return buf.String()
} }
func node_htmlFunc(node interface{}, fset *token.FileSet) string { func node_htmlFunc(info *PageInfo, node interface{}) string {
var buf1 bytes.Buffer var buf1 bytes.Buffer
writeNode(&buf1, fset, node) writeNode(&buf1, info.FSet, node)
var buf2 bytes.Buffer var buf2 bytes.Buffer
// BUG(gri): When showing full source text (?m=src), // Don't linkify full source text (info.PAst != nil) - identifier
// identifier links are incorrect. // resolution is not strong enough without full type checking.
// TODO(gri): Only linkify exported code snippets, not the if n, _ := node.(ast.Node); n != nil && *declLinks && info.PAst == nil {
// full source text: identifier resolution is
// not sufficiently strong w/o type checking.
// Need to check if info.PAst != nil - requires
// to pass *PageInfo around instead of fset.
if n, _ := node.(ast.Node); n != nil && *declLinks {
LinkifyText(&buf2, buf1.Bytes(), n) LinkifyText(&buf2, buf1.Bytes(), n)
} else { } else {
FormatText(&buf2, buf1.Bytes(), -1, true, "", nil) FormatText(&buf2, buf1.Bytes(), -1, true, "", nil)
...@@ -347,14 +342,14 @@ func stripExampleSuffix(name string) string { ...@@ -347,14 +342,14 @@ func stripExampleSuffix(name string) string {
return name return name
} }
func example_textFunc(funcName string, examples []*doc.Example, fset *token.FileSet, indent string) string { func example_textFunc(info *PageInfo, funcName, indent string) string {
if !*showExamples { if !*showExamples {
return "" return ""
} }
var buf bytes.Buffer var buf bytes.Buffer
first := true first := true
for _, eg := range examples { for _, eg := range info.Examples {
name := stripExampleSuffix(eg.Name) name := stripExampleSuffix(eg.Name)
if name != funcName { if name != funcName {
continue continue
...@@ -368,7 +363,7 @@ func example_textFunc(funcName string, examples []*doc.Example, fset *token.File ...@@ -368,7 +363,7 @@ func example_textFunc(funcName string, examples []*doc.Example, fset *token.File
// print code // print code
cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments} cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
var buf1 bytes.Buffer var buf1 bytes.Buffer
writeNode(&buf1, fset, cnode) writeNode(&buf1, info.FSet, cnode)
code := buf1.String() code := buf1.String()
// Additional formatting if this is a function body. // Additional formatting if this is a function body.
if n := len(code); n >= 2 && code[0] == '{' && code[n-1] == '}' { if n := len(code); n >= 2 && code[0] == '{' && code[n-1] == '}' {
...@@ -388,9 +383,9 @@ func example_textFunc(funcName string, examples []*doc.Example, fset *token.File ...@@ -388,9 +383,9 @@ func example_textFunc(funcName string, examples []*doc.Example, fset *token.File
return buf.String() return buf.String()
} }
func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.FileSet) string { func example_htmlFunc(info *PageInfo, funcName string) string {
var buf bytes.Buffer var buf bytes.Buffer
for _, eg := range examples { for _, eg := range info.Examples {
name := stripExampleSuffix(eg.Name) name := stripExampleSuffix(eg.Name)
if name != funcName { if name != funcName {
...@@ -399,7 +394,7 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File ...@@ -399,7 +394,7 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File
// print code // print code
cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments} cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
code := node_htmlFunc(cnode, fset) code := node_htmlFunc(info, cnode)
out := eg.Output out := eg.Output
wholeFile := true wholeFile := true
...@@ -421,7 +416,7 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File ...@@ -421,7 +416,7 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File
play := "" play := ""
if eg.Play != nil && *showPlayground { if eg.Play != nil && *showPlayground {
var buf bytes.Buffer var buf bytes.Buffer
if err := format.Node(&buf, fset, eg.Play); err != nil { if err := format.Node(&buf, info.FSet, eg.Play); err != nil {
log.Print(err) log.Print(err)
} else { } else {
play = buf.String() play = buf.String()
...@@ -486,19 +481,19 @@ func pkgLinkFunc(path string) string { ...@@ -486,19 +481,19 @@ func pkgLinkFunc(path string) string {
return pkgHandler.pattern[1:] + relpath // remove trailing '/' for relative URL return pkgHandler.pattern[1:] + relpath // remove trailing '/' for relative URL
} }
func posLink_urlFunc(node ast.Node, fset *token.FileSet) string { func posLink_urlFunc(info *PageInfo, node ast.Node) string {
var relpath string var relpath string
var line int var line int
var low, high int // selection var low, high int // selection
if p := node.Pos(); p.IsValid() { if p := node.Pos(); p.IsValid() {
pos := fset.Position(p) pos := info.FSet.Position(p)
relpath = pos.Filename relpath = pos.Filename
line = pos.Line line = pos.Line
low = pos.Offset low = pos.Offset
} }
if p := node.End(); p.IsValid() { if p := node.End(); p.IsValid() {
high = fset.Position(p).Offset high = info.FSet.Position(p).Offset
} }
var buf bytes.Buffer var buf bytes.Buffer
...@@ -1059,8 +1054,8 @@ func poorMansImporter(imports map[string]*ast.Object, path string) (*ast.Object, ...@@ -1059,8 +1054,8 @@ func poorMansImporter(imports map[string]*ast.Object, path string) (*ast.Object,
// directories, PageInfo.Dirs is nil. If an error occurred, PageInfo.Err is // directories, PageInfo.Dirs is nil. If an error occurred, PageInfo.Err is
// set to the respective error but the error is not logged. // set to the respective error but the error is not logged.
// //
func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (info PageInfo) { func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
info.Dirname = abspath info := &PageInfo{Dirname: abspath}
// Restrict to the package files that would be used when building // Restrict to the package files that would be used when building
// the package on this system. This makes sure that if there are // the package on this system. This makes sure that if there are
...@@ -1077,7 +1072,7 @@ func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (inf ...@@ -1077,7 +1072,7 @@ func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (inf
// continue if there are no Go source files; we still want the directory info // continue if there are no Go source files; we still want the directory info
if _, nogo := err.(*build.NoGoError); err != nil && !nogo { if _, nogo := err.(*build.NoGoError); err != nil && !nogo {
info.Err = err info.Err = err
return return info
} }
// collect package files // collect package files
...@@ -1100,7 +1095,7 @@ func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (inf ...@@ -1100,7 +1095,7 @@ func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (inf
files, err := parseFiles(fset, abspath, pkgfiles) files, err := parseFiles(fset, abspath, pkgfiles)
if err != nil { if err != nil {
info.Err = err info.Err = err
return return info
} }
// ignore any errors - they are due to unresolved identifiers // ignore any errors - they are due to unresolved identifiers
...@@ -1176,7 +1171,7 @@ func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (inf ...@@ -1176,7 +1171,7 @@ func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (inf
info.DirTime = timestamp info.DirTime = timestamp
info.DirFlat = mode&flatDir != 0 info.DirFlat = mode&flatDir != 0
return return info
} }
func (h *docServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *docServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
......
...@@ -374,14 +374,14 @@ func main() { ...@@ -374,14 +374,14 @@ func main() {
} }
// first, try as package unless forced as command // first, try as package unless forced as command
var info PageInfo var info *PageInfo
if !forceCmd { if !forceCmd {
info = pkgHandler.getPageInfo(abspath, relpath, mode) info = pkgHandler.getPageInfo(abspath, relpath, mode)
} }
// second, try as command unless the path is absolute // second, try as command unless the path is absolute
// (the go command invokes godoc w/ absolute paths; don't override) // (the go command invokes godoc w/ absolute paths; don't override)
var cinfo PageInfo var cinfo *PageInfo
if !filepath.IsAbs(path) { if !filepath.IsAbs(path) {
abspath = pathpkg.Join(cmdHandler.fsRoot, path) abspath = pathpkg.Join(cmdHandler.fsRoot, path)
cinfo = cmdHandler.getPageInfo(abspath, relpath, mode) cinfo = cmdHandler.getPageInfo(abspath, relpath, mode)
......
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