Skip to content

Commit 3cd2961

Browse files
authored
fix(internal/godocfx): use exact list of top-level decls (#3665)
1 parent fcb7318 commit 3cd2961

2 files changed

Lines changed: 52 additions & 11 deletions

File tree

internal/godocfx/parse.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
155155
// independently.
156156
for _, pi := range pkgInfos {
157157
link := newLinker(pi.pkg.Imports, pi.importRenames)
158+
topLevelDecls := pkgsite.TopLevelDecls(pi.doc)
158159
pkgItem := &item{
159160
UID: pi.doc.ImportPath,
160161
Name: pi.doc.ImportPath,
@@ -181,7 +182,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
181182
Type: "const",
182183
Summary: c.Doc,
183184
Langs: onlyGo,
184-
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL)},
185+
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL, topLevelDecls)},
185186
})
186187
}
187188
for _, v := range pi.doc.Vars {
@@ -197,7 +198,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
197198
Type: "variable",
198199
Summary: v.Doc,
199200
Langs: onlyGo,
200-
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL)},
201+
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL, topLevelDecls)},
201202
})
202203
}
203204
for _, t := range pi.doc.Types {
@@ -211,7 +212,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
211212
Type: "type",
212213
Summary: t.Doc,
213214
Langs: onlyGo,
214-
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, t.Decl, toURL)},
215+
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, t.Decl, toURL, topLevelDecls)},
215216
Examples: processExamples(t.Examples, pi.fset),
216217
}
217218
// Note: items are added as page.Children, rather than
@@ -230,7 +231,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
230231
Type: "const",
231232
Summary: c.Doc,
232233
Langs: onlyGo,
233-
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL)},
234+
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL, topLevelDecls)},
234235
})
235236
}
236237
for _, v := range t.Vars {
@@ -246,7 +247,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
246247
Type: "variable",
247248
Summary: v.Doc,
248249
Langs: onlyGo,
249-
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL)},
250+
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL, topLevelDecls)},
250251
})
251252
}
252253

@@ -336,7 +337,6 @@ func (l *linker) linkify(s string) string {
336337
prefix += "*"
337338
}
338339

339-
// If s does not have a dot, it's in this package.
340340
if !strings.Contains(s, ".") {
341341
// If s is not exported, it's probably a builtin.
342342
if !token.IsExported(s) {

third_party/pkgsite/print_type.go

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ import (
3636
// 4. Use scanner.Scanner to find every identifier (in the same order as step
3737
// 2). If there is a link for the identifier, insert it. Otherwise, print
3838
// the plain doc.
39-
func PrintType(fset *token.FileSet, decl ast.Decl, toURL func(string, string) string) string {
40-
anchorLinksMap := generateAnchorLinks(decl, toURL)
39+
func PrintType(fset *token.FileSet, decl ast.Decl, toURL func(string, string) string, topLevelDecls map[interface{}]bool) string {
40+
anchorLinksMap := generateAnchorLinks(decl, toURL, topLevelDecls)
4141
// Convert the map (keyed by *ast.Ident) to a slice of URLs (or no URL).
4242
//
4343
// This relies on the ast.Inspect and scanner.Scanner both
@@ -149,7 +149,7 @@ func stringBasicLitSize(s string) string {
149149

150150
// generateAnchorLinks returns a mapping of *ast.Ident objects to the URL
151151
// that the identifier should link to.
152-
func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string) map[*ast.Ident]string {
152+
func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string, topLevelDecls map[interface{}]bool) map[*ast.Ident]string {
153153
m := map[*ast.Ident]string{}
154154
ignore := map[ast.Node]bool{}
155155
ast.Inspect(decl, func(node ast.Node) bool {
@@ -175,8 +175,7 @@ func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string) map[*
175175
case *ast.Ident:
176176
if node.Obj == nil && doc.IsPredeclared(node.Name) {
177177
m[node] = toURL("builtin", node.Name)
178-
} else if node.Obj != nil && node.Obj.Kind != ast.Var {
179-
// TODO: && topLevelDecls[node.Obj.Decl]
178+
} else if node.Obj != nil && topLevelDecls[node.Obj.Decl] {
180179
m[node] = toURL("", node.Name)
181180
}
182181
case *ast.FuncDecl:
@@ -196,3 +195,45 @@ func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string) map[*
196195
})
197196
return m
198197
}
198+
199+
// TopLevelDecls returns the top level declarations in the package.
200+
func TopLevelDecls(pkg *doc.Package) map[interface{}]bool {
201+
topLevelDecls := map[interface{}]bool{}
202+
forEachPackageDecl(pkg, func(decl ast.Decl) {
203+
topLevelDecls[decl] = true
204+
if gd, _ := decl.(*ast.GenDecl); gd != nil {
205+
for _, sp := range gd.Specs {
206+
topLevelDecls[sp] = true
207+
}
208+
}
209+
})
210+
return topLevelDecls
211+
}
212+
213+
// forEachPackageDecl iterates though every top-level declaration in a package.
214+
func forEachPackageDecl(pkg *doc.Package, fnc func(decl ast.Decl)) {
215+
for _, c := range pkg.Consts {
216+
fnc(c.Decl)
217+
}
218+
for _, v := range pkg.Vars {
219+
fnc(v.Decl)
220+
}
221+
for _, f := range pkg.Funcs {
222+
fnc(f.Decl)
223+
}
224+
for _, t := range pkg.Types {
225+
fnc(t.Decl)
226+
for _, c := range t.Consts {
227+
fnc(c.Decl)
228+
}
229+
for _, v := range t.Vars {
230+
fnc(v.Decl)
231+
}
232+
for _, f := range t.Funcs {
233+
fnc(f.Decl)
234+
}
235+
for _, m := range t.Methods {
236+
fnc(m.Decl)
237+
}
238+
}
239+
}

0 commit comments

Comments
 (0)