Skip to content
Permalink
Browse files
fix(internal/godocfx): use exact list of top-level decls (#3665)
  • Loading branch information
tbpg committed Feb 3, 2021
1 parent fcb7318 commit 3cd2961bd7b9c29d82a21ba8850eff00c7c332fd
Showing with 52 additions and 11 deletions.
  1. +6 −6 internal/godocfx/parse.go
  2. +46 −5 third_party/pkgsite/print_type.go
@@ -155,6 +155,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
// independently.
for _, pi := range pkgInfos {
link := newLinker(pi.pkg.Imports, pi.importRenames)
topLevelDecls := pkgsite.TopLevelDecls(pi.doc)
pkgItem := &item{
UID: pi.doc.ImportPath,
Name: pi.doc.ImportPath,
@@ -181,7 +182,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
Type: "const",
Summary: c.Doc,
Langs: onlyGo,
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL)},
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL, topLevelDecls)},
})
}
for _, v := range pi.doc.Vars {
@@ -197,7 +198,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
Type: "variable",
Summary: v.Doc,
Langs: onlyGo,
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL)},
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL, topLevelDecls)},
})
}
for _, t := range pi.doc.Types {
@@ -211,7 +212,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
Type: "type",
Summary: t.Doc,
Langs: onlyGo,
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, t.Decl, toURL)},
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, t.Decl, toURL, topLevelDecls)},
Examples: processExamples(t.Examples, pi.fset),
}
// Note: items are added as page.Children, rather than
@@ -230,7 +231,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
Type: "const",
Summary: c.Doc,
Langs: onlyGo,
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL)},
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, c.Decl, toURL, topLevelDecls)},
})
}
for _, v := range t.Vars {
@@ -246,7 +247,7 @@ func parse(glob string, workingDir string, optionalExtraFiles []string) (*result
Type: "variable",
Summary: v.Doc,
Langs: onlyGo,
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL)},
Syntax: syntax{Content: pkgsite.PrintType(pi.fset, v.Decl, toURL, topLevelDecls)},
})
}

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

// If s does not have a dot, it's in this package.
if !strings.Contains(s, ".") {
// If s is not exported, it's probably a builtin.
if !token.IsExported(s) {
@@ -36,8 +36,8 @@ import (
// 4. Use scanner.Scanner to find every identifier (in the same order as step
// 2). If there is a link for the identifier, insert it. Otherwise, print
// the plain doc.
func PrintType(fset *token.FileSet, decl ast.Decl, toURL func(string, string) string) string {
anchorLinksMap := generateAnchorLinks(decl, toURL)
func PrintType(fset *token.FileSet, decl ast.Decl, toURL func(string, string) string, topLevelDecls map[interface{}]bool) string {
anchorLinksMap := generateAnchorLinks(decl, toURL, topLevelDecls)
// Convert the map (keyed by *ast.Ident) to a slice of URLs (or no URL).
//
// This relies on the ast.Inspect and scanner.Scanner both
@@ -149,7 +149,7 @@ func stringBasicLitSize(s string) string {

// generateAnchorLinks returns a mapping of *ast.Ident objects to the URL
// that the identifier should link to.
func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string) map[*ast.Ident]string {
func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string, topLevelDecls map[interface{}]bool) map[*ast.Ident]string {
m := map[*ast.Ident]string{}
ignore := map[ast.Node]bool{}
ast.Inspect(decl, func(node ast.Node) bool {
@@ -175,8 +175,7 @@ func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string) map[*
case *ast.Ident:
if node.Obj == nil && doc.IsPredeclared(node.Name) {
m[node] = toURL("builtin", node.Name)
} else if node.Obj != nil && node.Obj.Kind != ast.Var {
// TODO: && topLevelDecls[node.Obj.Decl]
} else if node.Obj != nil && topLevelDecls[node.Obj.Decl] {
m[node] = toURL("", node.Name)
}
case *ast.FuncDecl:
@@ -196,3 +195,45 @@ func generateAnchorLinks(decl ast.Decl, toURL func(string, string) string) map[*
})
return m
}

// TopLevelDecls returns the top level declarations in the package.
func TopLevelDecls(pkg *doc.Package) map[interface{}]bool {
topLevelDecls := map[interface{}]bool{}
forEachPackageDecl(pkg, func(decl ast.Decl) {
topLevelDecls[decl] = true
if gd, _ := decl.(*ast.GenDecl); gd != nil {
for _, sp := range gd.Specs {
topLevelDecls[sp] = true
}
}
})
return topLevelDecls
}

// forEachPackageDecl iterates though every top-level declaration in a package.
func forEachPackageDecl(pkg *doc.Package, fnc func(decl ast.Decl)) {
for _, c := range pkg.Consts {
fnc(c.Decl)
}
for _, v := range pkg.Vars {
fnc(v.Decl)
}
for _, f := range pkg.Funcs {
fnc(f.Decl)
}
for _, t := range pkg.Types {
fnc(t.Decl)
for _, c := range t.Consts {
fnc(c.Decl)
}
for _, v := range t.Vars {
fnc(v.Decl)
}
for _, f := range t.Funcs {
fnc(f.Decl)
}
for _, m := range t.Methods {
fnc(m.Decl)
}
}
}

0 comments on commit 3cd2961

Please sign in to comment.