getting a function docs when you have a *packages.Package

43 views
Skip to first unread message

Dan Kortschak

unread,
Dec 6, 2019, 4:38:04 PM12/6/19
to golang-nuts
I want to be able to extract function documentation in addition to a
variety of other information. I have a *packages.Package from
packages.Load. Is there an easy way to get the function documentation
from this. At the moment I am obtaining a *doc.Package using the
following code, but it seems more complicated than necessary and it
returns errors (I think) because I do not have an ast.Importer and I
don't see a place to get one.

files := make(map[string]*ast.File)
for _, f := range pkg.Syntax {
files[f.Name.Name] = f
}
astPkg, err := ast.NewPackage(pkg.Fset, files, nil, ast.NewScope(nil))
if err != nil {
log.Printf("error preparing docs: %v", err)
}
docs := doc.New(astPkg, pkg.PkgPath, doc.PreserveAST)

Is there a more sensible way to do this?

thanks
Dan

Charith Ellawala

unread,
Dec 7, 2019, 12:12:44 PM12/7/19
to golang-nuts
I am searching for a good way of doing this myself. An approach that seems to work reasonably well is to just iterate through the AST files and extract the function declarations:

cfg := &packages.Config{
   
Mode: packages.NeedName | packages.NeedTypes | packages.NeedSyntax | packages.NeedFiles,
   
Dir:  os.Args[1],
}

// packages.Load code omitted

for _, file := range pkg.Syntax {
   
for _, decl := range file.Decls {
       
if fn, ok := decl.(*ast.FuncDecl); ok {
            fmt
.Printf("func %s\n", fn.Name)
           
if fn.Doc != nil {
                fmt
.Println(fn.Doc.Text())
           
}
       
}
   
}
}


I think there are some edge cases that this cannot handle such as "floating" comments. I mainly work with Kubernetes code so I use the markers package from controller-tools -- which seems to handle those cases. The code is quite complicated and I haven't had time to dive deeper and understand exactly how they do it. Perhaps you will be able to find some pointers there.

Dan Kortschak

unread,
Dec 7, 2019, 5:01:06 PM12/7/19
to Charith Ellawala, golang-nuts
I completely missed the .Doc field in the ast.FuncDecl type. That's
perfect. Thanks.

On Sat, 2019-12-07 at 03:47 -0800, Charith Ellawala wrote:
> I am searching for a good way of doing this myself. An approach that
> seems
> to work reasonably well is to just iterate through the AST files and
> extract the function declarations:
>
> cfg := &packages.Config{
> Mode: packages.NeedName | packages.NeedTypes |
> packages.NeedSyntax |
> packages.NeedFiles,
> Dir: os.Args[1],
> }
>
> // packages.Load code omitted
>
> for _, file := range pkg.Syntax {
> for _, decl := range file.Decls {
> if fn, ok := decl.(*ast.FuncDecl); ok {
> fmt.Printf("func %s\n", fn.Name)
> if fn.Doc != nil {
> fmt.Println(fn.Doc.Text())
> }
> }
> }
> }
>
>
> I think there are some edge cases that this cannot handle such as
> "floating" comments. I mainly work with Kubernetes code so I use the
> markers
> package <https://godoc.org/sigs.k8s.io/controller-tools/pkg/markers>
Reply all
Reply to author
Forward
0 new messages