Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(internal/godocfx): use exact list of top-level decls #3665

Merged
merged 1 commit into from Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions internal/godocfx/parse.go
Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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 {
Expand All @@ -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)},
})
}

Expand Down Expand Up @@ -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) {
Expand Down
51 changes: 46 additions & 5 deletions third_party/pkgsite/print_type.go
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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:
Expand All @@ -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)
}
}
}