Skip to content

Commit e599a2b

Browse files
committed
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 golang#259. A gddo server with this change applied is temporarily available at http://godoc.sgdev.org/. Change-Id: Ifa7773b56ccc08c8f063730bdf1fa441d9728d5c
1 parent a9487c4 commit e599a2b

File tree

5 files changed

+58
-6
lines changed

5 files changed

+58
-6
lines changed

doc/builder.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ type Func struct {
254254
Pos Pos
255255
Doc string
256256
Name string
257-
Recv string
257+
Recv string // Actual receiver "T" or "*T".
258+
Orig string // Original receiver "T" or "*T". This can be different from Recv due to embedding.
258259
Examples []*Example
259260
}
260261

@@ -276,6 +277,7 @@ func (b *builder) funcs(fdocs []*doc.Func) []*Func {
276277
Doc: d.Doc,
277278
Name: d.Name,
278279
Recv: d.Recv,
280+
Orig: d.Orig,
279281
Examples: b.getExamples(exampleName),
280282
})
281283
}

gddo-server/assets/site.css

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,13 @@ a.permalink {
111111
display: none;
112112
}
113113

114-
h1:hover .permalink, h2:hover .permalink, h3:hover .permalink, h4:hover .permalink, h5:hover .permalink, h6:hover .permalink {
114+
a.uses {
115+
display: none;
116+
color: #666;
117+
font-size: 0.8em;
118+
}
119+
120+
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 {
115121
display: inline;
116122
}
117123

gddo-server/assets/templates/pkg.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ <h3 id="pkg-variables">Variables <a class="permalink" href="#pkg-variables">&par
108108
<h3 id="pkg-functions" class="section-header">Functions <a class="permalink" href="#pkg-functions">&para;</a></h3>
109109
{{end}}{{end}}
110110
{{range .Funcs}}
111-
<h3 id="{{.Name}}" data-kind="f">func {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a></h3>
111+
<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>
112112
<div class="funcdecl decl">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}
113113
{{template "Examples" .|$.pdoc.ObjExamples}}
114114
{{end}}
@@ -119,20 +119,20 @@ <h3 id="pkg-types" class="section-header">Types <a class="permalink" href="#pkg-
119119
{{end}}{{end}}
120120

121121
{{range $t := .Types}}
122-
<h3 id="{{.Name}}" data-kind="t">type {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a></h3>
122+
<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>
123123
<div class="decl" data-kind="{{if isInterface $t}}m{{else}}d{{end}}">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl $t}}</div>{{.Doc|comment}}
124124
{{range .Consts}}<div class="decl" data-kind="c">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}{{end}}
125125
{{range .Vars}}<div class="decl" data-kind="v">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}{{end}}
126126
{{template "Examples" .|$.pdoc.ObjExamples}}
127127

128128
{{range .Funcs}}
129-
<h4 id="{{.Name}}" data-kind="f">func {{$.pdoc.SourceLink .Pos .Name true}} <a class="permalink" href="#{{.Name}}">&para;</a></h4>
129+
<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>
130130
<div class="funcdecl decl">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}
131131
{{template "Examples" .|$.pdoc.ObjExamples}}
132132
{{end}}
133133

134134
{{range .Methods}}
135-
<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>
135+
<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>
136136
<div class="funcdecl decl">{{$.pdoc.SourceLink .Pos "\u2756" false}}{{code .Decl nil}}</div>{{.Doc|comment}}
137137
{{template "Examples" .|$.pdoc.ObjExamples}}
138138
{{end}}

gddo-server/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ var (
856856
sidebarEnabled = flag.Bool("sidebar", false, "Enable package page sidebar.")
857857
defaultGOOS = flag.String("default_goos", "", "Default GOOS to use when building package documents.")
858858
trustProxy = flag.Bool("trust_proxy_headers", false, "If enabled, identify the remote address of the request using X-Real-Ip in header.")
859+
sourcegraphURL = flag.String("sourcegraph_url", "https://sourcegraph.com", "Link to global uses on Sourcegraph based at this URL (no need for trailing slash).")
859860
)
860861

861862
func main() {

gddo-server/template.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,49 @@ func (pdoc *tdoc) SourceLink(pos doc.Pos, text string, textOnlyOK bool) htemp.HT
105105
htemp.HTMLEscapeString(text)))
106106
}
107107

108+
// UsesLink generates a link to uses of a symbol definition.
109+
// title is used as the tooltip. defParts are parts of the symbol definition name.
110+
func (pdoc *tdoc) UsesLink(title string, defParts ...string) htemp.HTML {
111+
if *sourcegraphURL == "" {
112+
return ""
113+
}
114+
115+
var def string
116+
switch len(defParts) {
117+
case 1:
118+
// Funcs and types have one def part.
119+
def = defParts[0]
120+
121+
case 3:
122+
// Methods have three def parts, the original receiver name, actual receiver name and method name.
123+
orig, recv, methodName := defParts[0], defParts[1], defParts[2]
124+
125+
if orig == "" {
126+
// TODO: Remove this fallback after 2016-08-05. It's only needed temporarily to backfill data.
127+
// Actual receiver is not needed, it's only used because original receiver value
128+
// was recently added to gddo/doc package and will be blank until next package rebuild.
129+
//
130+
// Use actual receiver as fallback.
131+
orig = recv
132+
}
133+
134+
// Trim "*" from "*T" if it's a pointer receiver method.
135+
typeName := strings.TrimPrefix(orig, "*")
136+
137+
def = typeName + "/" + methodName
138+
default:
139+
panic(fmt.Errorf("internal error: UsesLink provided %v len(defParts), expected 1 or 3", len(defParts)))
140+
}
141+
142+
q := url.Values{
143+
"repo": {pdoc.ProjectRoot},
144+
"pkg": {pdoc.ImportPath},
145+
"def": {def},
146+
}
147+
u := *sourcegraphURL + "/-/godoc/refs?" + q.Encode()
148+
return htemp.HTML(fmt.Sprintf(`<a class="uses" title="%s" href="%s">Uses</a>`, htemp.HTMLEscapeString(title), htemp.HTMLEscapeString(u)))
149+
}
150+
108151
func (pdoc *tdoc) PageName() string {
109152
if pdoc.Name != "" && !pdoc.IsCmd {
110153
return pdoc.Name

0 commit comments

Comments
 (0)