@@ -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