gddo-server: add global "Uses" links (alongside permalinks)

Each definition's "Uses" link points to the definition's page on
Sourcegraph, which shows where the definition is used (across all
indexed open-source repositories). This lets library users see "usage
examples" and gives library authors information about how their
library's API is being used.

It is necessary to store the value of go/doc.Func.Orig (the original
receiver name, see https://godoc.org/go/doc#Func.Orig) when building
documentation. Previously, only go/doc.Func.Recv (actual receiver
name) was stored. The original receiver name can differ from actual
due to struct embedding.

This change was originally submitted and OK'd by adg at
https://github.com/golang/gddo/pull/259.

A gddo server with this change applied is temporarily available at
http://godoc.sgdev.org/.

Change-Id: Ifa7773b56ccc08c8f063730bdf1fa441d9728d5c
Reviewed-on: https://go-review.googlesource.com/23380
Reviewed-by: Andrew Gerrand <adg@golang.org>
diff --git a/doc/builder.go b/doc/builder.go
index a2b6e14..4b20837 100644
--- a/doc/builder.go
+++ b/doc/builder.go
@@ -254,7 +254,8 @@
 	Pos      Pos
 	Doc      string
 	Name     string
-	Recv     string
+	Recv     string // Actual receiver "T" or "*T".
+	Orig     string // Original receiver "T" or "*T". This can be different from Recv due to embedding.
 	Examples []*Example
 }
 
@@ -276,6 +277,7 @@
 			Doc:      d.Doc,
 			Name:     d.Name,
 			Recv:     d.Recv,
+			Orig:     d.Orig,
 			Examples: b.getExamples(exampleName),
 		})
 	}
diff --git a/gddo-server/assets/site.css b/gddo-server/assets/site.css
index bb270d7..cf11b78 100644
--- a/gddo-server/assets/site.css
+++ b/gddo-server/assets/site.css
@@ -111,7 +111,13 @@
     display: none;
 }
 
-h1:hover .permalink, h2:hover .permalink, h3:hover .permalink, h4:hover .permalink, h5:hover .permalink, h6:hover .permalink {
+a.uses {
+    display: none;
+    color: #666;
+    font-size: 0.8em;
+}
+
+h1:hover .permalink, h2:hover .permalink, h3:hover .permalink, h4:hover .permalink, h5:hover .permalink, h6:hover .permalink, h1:hover .uses, h2:hover .uses, h3:hover .uses, h4:hover .uses, h5:hover .uses, h6:hover .uses {
     display: inline;
 }
 
diff --git a/gddo-server/assets/templates/pkg.html b/gddo-server/assets/templates/pkg.html
index 50916a5..49f0c31 100644
--- a/gddo-server/assets/templates/pkg.html
+++ b/gddo-server/assets/templates/pkg.html
@@ -108,7 +108,7 @@
             <h3 id="pkg-functions" class="section-header">Functions <a class="permalink" href="#pkg-functions">&para;</a></h3>
         {{end}}{{end}}
         {{range .Funcs}}
-          <h3 id="{{.Name}}" data-kind="f">func {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a></h3>
+          <h3 id="{{.Name}}" data-kind="f">func {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a> {{$.pdoc.UsesLink "List Function Callers" .Name}}</h3>
           <div class="funcdecl decl">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}
           {{template "Examples" .|$.pdoc.ObjExamples}}
         {{end}}
@@ -119,20 +119,20 @@
         {{end}}{{end}}
 
         {{range $t := .Types}}
-          <h3 id="{{.Name}}" data-kind="t">type {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a></h3>
+          <h3 id="{{.Name}}" data-kind="t">type {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a> {{$.pdoc.UsesLink "List Uses of This Type" .Name}}</h3>
           <div class="decl" data-kind="{{if isInterface $t}}m{{else}}d{{end}}">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl $t}}</div>{{.Doc|comment}}
           {{range .Consts}}<div class="decl" data-kind="c">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}{{end}}
           {{range .Vars}}<div class="decl" data-kind="v">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}{{end}}
           {{template "Examples" .|$.pdoc.ObjExamples}}
 
           {{range .Funcs}}
-            <h4 id="{{.Name}}" data-kind="f">func {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a></h4>
+            <h4 id="{{.Name}}" data-kind="f">func {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a> {{$.pdoc.UsesLink "List Function Callers" .Name}}</h4>
             <div class="funcdecl decl">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}
             {{template "Examples" .|$.pdoc.ObjExamples}}
           {{end}}
 
           {{range .Methods}}
-            <h4 id="{{$t.Name}}.{{.Name}}" data-kind="m">func ({{.Recv}}) {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{$t.Name}}.{{.Name}}">&para;</a></h4>
+            <h4 id="{{$t.Name}}.{{.Name}}" data-kind="m">func ({{.Recv}}) {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{$t.Name}}.{{.Name}}">&para;</a> {{$.pdoc.UsesLink "List Method Callers" .Orig .Recv .Name}}</h4>
             <div class="funcdecl decl">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}
             {{template "Examples" .|$.pdoc.ObjExamples}}
           {{end}}
diff --git a/gddo-server/main.go b/gddo-server/main.go
index f79bff3..31bb818 100644
--- a/gddo-server/main.go
+++ b/gddo-server/main.go
@@ -856,6 +856,7 @@
 	sidebarEnabled  = flag.Bool("sidebar", false, "Enable package page sidebar.")
 	defaultGOOS     = flag.String("default_goos", "", "Default GOOS to use when building package documents.")
 	trustProxy      = flag.Bool("trust_proxy_headers", false, "If enabled, identify the remote address of the request using X-Real-Ip in header.")
+	sourcegraphURL  = flag.String("sourcegraph_url", "https://sourcegraph.com", "Link to global uses on Sourcegraph based at this URL (no need for trailing slash).")
 )
 
 func main() {
diff --git a/gddo-server/template.go b/gddo-server/template.go
index c234d3f..b7bf32e 100644
--- a/gddo-server/template.go
+++ b/gddo-server/template.go
@@ -105,6 +105,49 @@
 		htemp.HTMLEscapeString(text)))
 }
 
+// UsesLink generates a link to uses of a symbol definition.
+// title is used as the tooltip. defParts are parts of the symbol definition name.
+func (pdoc *tdoc) UsesLink(title string, defParts ...string) htemp.HTML {
+	if *sourcegraphURL == "" {
+		return ""
+	}
+
+	var def string
+	switch len(defParts) {
+	case 1:
+		// Funcs and types have one def part.
+		def = defParts[0]
+
+	case 3:
+		// Methods have three def parts, the original receiver name, actual receiver name and method name.
+		orig, recv, methodName := defParts[0], defParts[1], defParts[2]
+
+		if orig == "" {
+			// TODO: Remove this fallback after 2016-08-05. It's only needed temporarily to backfill data.
+			//       Actual receiver is not needed, it's only used because original receiver value
+			//       was recently added to gddo/doc package and will be blank until next package rebuild.
+			//
+			// Use actual receiver as fallback.
+			orig = recv
+		}
+
+		// Trim "*" from "*T" if it's a pointer receiver method.
+		typeName := strings.TrimPrefix(orig, "*")
+
+		def = typeName + "/" + methodName
+	default:
+		panic(fmt.Errorf("%v defParts, want 1 or 3", len(defParts)))
+	}
+
+	q := url.Values{
+		"repo": {pdoc.ProjectRoot},
+		"pkg":  {pdoc.ImportPath},
+		"def":  {def},
+	}
+	u := *sourcegraphURL + "/-/godoc/refs?" + q.Encode()
+	return htemp.HTML(fmt.Sprintf(`<a class="uses" title="%s" href="%s">Uses</a>`, htemp.HTMLEscapeString(title), htemp.HTMLEscapeString(u)))
+}
+
 func (pdoc *tdoc) PageName() string {
 	if pdoc.Name != "" && !pdoc.IsCmd {
 		return pdoc.Name