go.tools/godoc: server mode: add support for type and pointer analysis.
See analysis.go for overview of new features.
See README for known bugs and issues.
Much UI polish, testing and optimization work remains, but
this is a starting point.
Flag: we add a new flag -analysis=type,pointer, default "",
for adventurous users only at this stage.
Type analysis takes ~10s for stdlib + go.tools;
Pointer analysis (currently) takes several minutes.
Dependencies: we now include jquery.treeview.js and its GIF
images among the resources. (bake.go now handles binary.)
LGTM=crawshaw, bgarcia
R=crawshaw, bgarcia
CC=bradfitz, golang-codereviews
https://golang.org/cl/60540044
diff --git a/godoc/godoc.go b/godoc/godoc.go
index ed63d4e..3cb1f21 100644
--- a/godoc/godoc.go
+++ b/godoc/godoc.go
@@ -17,6 +17,7 @@
"go/format"
"go/printer"
"go/token"
+ htmltemplate "html/template"
"io"
"log"
"os"
@@ -89,6 +90,11 @@
"example_name": p.example_nameFunc,
"example_suffix": p.example_suffixFunc,
+ // formatting of analysis information
+ "callgraph_html": p.callgraph_htmlFunc,
+ "implements_html": p.implements_htmlFunc,
+ "methodset_html": p.methodset_htmlFunc,
+
// formatting of Notes
"noteTitle": noteTitle,
}
@@ -235,6 +241,12 @@
IsMain bool // true for package main
IsFiltered bool // true if results were filtered
+ // analysis info
+ TypeInfoIndex map[string]int // index of JSON datum for type T (if -analysis=type)
+ AnalysisData htmltemplate.JS // array of TypeInfoJSON values
+ CallGraph htmltemplate.JS // array of PCGNodeJSON values (if -analysis=pointer)
+ CallGraphIndex map[string]int // maps func name to index in CallGraph
+
// directory info
Dirs *DirList // nil if no directory information
DirTime time.Time // directory time stamp
@@ -456,6 +468,64 @@
return suffix
}
+// implements_html returns the "> Implements" toggle for a package-level named type.
+// Its contents are populated from JSON data by client-side JS at load time.
+func (p *Presentation) implements_htmlFunc(info *PageInfo, typeName string) string {
+ if p.ImplementsHTML == nil {
+ return ""
+ }
+ index, ok := info.TypeInfoIndex[typeName]
+ if !ok {
+ return ""
+ }
+ var buf bytes.Buffer
+ err := p.ImplementsHTML.Execute(&buf, struct{ Index int }{index})
+ if err != nil {
+ log.Print(err)
+ }
+ return buf.String()
+}
+
+// methodset_html returns the "> Method set" toggle for a package-level named type.
+// Its contents are populated from JSON data by client-side JS at load time.
+func (p *Presentation) methodset_htmlFunc(info *PageInfo, typeName string) string {
+ if p.MethodSetHTML == nil {
+ return ""
+ }
+ index, ok := info.TypeInfoIndex[typeName]
+ if !ok {
+ return ""
+ }
+ var buf bytes.Buffer
+ err := p.MethodSetHTML.Execute(&buf, struct{ Index int }{index})
+ if err != nil {
+ log.Print(err)
+ }
+ return buf.String()
+}
+
+// callgraph_html returns the "> Call graph" toggle for a package-level func.
+// Its contents are populated from JSON data by client-side JS at load time.
+func (p *Presentation) callgraph_htmlFunc(info *PageInfo, recv, name string) string {
+ if p.CallGraphHTML == nil {
+ return ""
+ }
+ if recv != "" {
+ // Format must match (*ssa.Function).RelString().
+ name = fmt.Sprintf("(%s).%s", recv, name)
+ }
+ index, ok := info.CallGraphIndex[name]
+ if !ok {
+ return ""
+ }
+ var buf bytes.Buffer
+ err := p.CallGraphHTML.Execute(&buf, struct{ Index int }{index})
+ if err != nil {
+ log.Print(err)
+ }
+ return buf.String()
+}
+
func noteTitle(note string) string {
return strings.Title(strings.ToLower(note))
}