mirror of
https://github.com/readthedocs/sphinx-autoapi
synced 2024-11-17 21:25:35 +00:00
175 lines
5.2 KiB
Go
175 lines
5.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"go/doc"
|
|
"go/parser"
|
|
"go/token"
|
|
"os"
|
|
)
|
|
|
|
// Func represents a function declaration.
|
|
type Func struct {
|
|
Doc string `json:"doc"`
|
|
Name string `json:"name"`
|
|
PackageName string `json:"packageName"`
|
|
PackageImportPath string `json:"packageImportPath"`
|
|
// Decl *ast.FuncDecl
|
|
|
|
// methods
|
|
// (for functions, these fields have the respective zero value)
|
|
Recv string `json:"recv"` // actual receiver "T" or "*T"
|
|
Orig string `json:"orig"` // original receiver "T" or "*T"
|
|
// Level int // embedding level; 0 means not embedded
|
|
}
|
|
|
|
// Package represents a package declaration.
|
|
type Package struct {
|
|
Type string `json:"type"`
|
|
Doc string `json:"doc"`
|
|
Name string `json:"name"`
|
|
ImportPath string `json:"importPath"`
|
|
Imports []string `json:"imports"`
|
|
Filenames []string `json:"filenames"`
|
|
Notes map[string][]*Note `json:"notes"`
|
|
// DEPRECATED. For backward compatibility Bugs is still populated,
|
|
// but all new code should use Notes instead.
|
|
Bugs []string `json:"bugs"`
|
|
|
|
// declarations
|
|
Consts []*Value `json:"consts"`
|
|
Types []*Type `json:"types"`
|
|
Vars []*Value `json:"vars"`
|
|
Funcs []*Func `json:"funcs"`
|
|
}
|
|
|
|
// Note represents a note comment.
|
|
type Note struct {
|
|
Pos token.Pos `json:"pos"`
|
|
End token.Pos `json:"end"` // position range of the comment containing the marker
|
|
UID string `json:"uid"` // uid found with the marker
|
|
Body string `json:"body"` // note body text
|
|
}
|
|
|
|
// Type represents a type declaration.
|
|
type Type struct {
|
|
PackageName string `json:"packageName"`
|
|
PackageImportPath string `json:"packageImportPath"`
|
|
Doc string `json:"doc"`
|
|
Name string `json:"name"`
|
|
// Decl *ast.GenDecl
|
|
|
|
// associated declarations
|
|
Consts []*Value `json:"consts"` // sorted list of constants of (mostly) this type
|
|
Vars []*Value `json:"vars"` // sorted list of variables of (mostly) this type
|
|
Funcs []*Func `json:"funcs"` // sorted list of functions returning this type
|
|
Methods []*Func `json:"methods"` // sorted list of methods (including embedded ones) of this type
|
|
}
|
|
|
|
// Value represents a value declaration.
|
|
type Value struct {
|
|
PackageName string `json:"packageName"`
|
|
PackageImportPath string `json:"packageImportPath"`
|
|
Doc string `json:"doc"`
|
|
Names []string `json:"names"` // var or const names in declaration order
|
|
// Decl *ast.GenDecl
|
|
}
|
|
|
|
// CopyFuncs produces a json-annotated array of Func objects from an array of GoDoc Func objects.
|
|
func CopyFuncs(f []*doc.Func, packageName string, packageImportPath string) []*Func {
|
|
newFuncs := make([]*Func, len(f))
|
|
for i, n := range f {
|
|
newFuncs[i] = &Func{
|
|
Doc: n.Doc,
|
|
Name: n.Name,
|
|
PackageName: packageName,
|
|
PackageImportPath: packageImportPath,
|
|
Orig: n.Orig,
|
|
Recv: n.Recv,
|
|
}
|
|
}
|
|
return newFuncs
|
|
}
|
|
|
|
// CopyValues produces a json-annotated array of Value objects from an array of GoDoc Value objects.
|
|
func CopyValues(c []*doc.Value, packageName string, packageImportPath string) []*Value {
|
|
newConsts := make([]*Value, len(c))
|
|
for i, c := range c {
|
|
newConsts[i] = &Value{
|
|
Doc: c.Doc,
|
|
Names: c.Names,
|
|
PackageName: packageName,
|
|
PackageImportPath: packageImportPath,
|
|
}
|
|
}
|
|
return newConsts
|
|
}
|
|
|
|
// CopyPackage produces a json-annotated Package object from a GoDoc Package object.
|
|
func CopyPackage(pkg *doc.Package) Package {
|
|
newPkg := Package{
|
|
Type: "package",
|
|
Doc: pkg.Doc,
|
|
Name: pkg.Name,
|
|
ImportPath: pkg.ImportPath,
|
|
Imports: pkg.Imports,
|
|
Filenames: pkg.Filenames,
|
|
Bugs: pkg.Bugs,
|
|
}
|
|
|
|
newPkg.Notes = map[string][]*Note{}
|
|
for key, value := range pkg.Notes {
|
|
notes := make([]*Note, len(value))
|
|
for i, note := range value {
|
|
notes[i] = &Note{
|
|
Pos: note.Pos,
|
|
End: note.End,
|
|
UID: note.UID,
|
|
Body: note.Body,
|
|
}
|
|
}
|
|
newPkg.Notes[key] = notes
|
|
}
|
|
|
|
newPkg.Consts = CopyValues(pkg.Consts, pkg.Name, pkg.ImportPath)
|
|
newPkg.Funcs = CopyFuncs(pkg.Funcs, pkg.Name, pkg.ImportPath)
|
|
|
|
newPkg.Types = make([]*Type, len(pkg.Types))
|
|
for i, t := range pkg.Types {
|
|
newPkg.Types[i] = &Type{
|
|
Name: t.Name,
|
|
PackageName: pkg.Name,
|
|
PackageImportPath: pkg.ImportPath,
|
|
Consts: CopyValues(t.Consts, pkg.Name, pkg.ImportPath),
|
|
Doc: t.Doc,
|
|
Funcs: CopyFuncs(t.Funcs, pkg.Name, pkg.ImportPath),
|
|
Methods: CopyFuncs(t.Methods, pkg.Name, pkg.ImportPath),
|
|
Vars: CopyValues(t.Vars, pkg.Name, pkg.ImportPath),
|
|
}
|
|
}
|
|
|
|
newPkg.Vars = CopyValues(pkg.Vars, pkg.Name, pkg.ImportPath)
|
|
return newPkg
|
|
}
|
|
|
|
func main() {
|
|
directories := os.Args[1:]
|
|
for _, dir := range directories {
|
|
fileSet := token.NewFileSet()
|
|
pkgs, firstError := parser.ParseDir(fileSet, dir, nil, parser.ParseComments|parser.AllErrors)
|
|
if firstError != nil {
|
|
panic(firstError)
|
|
}
|
|
for _, pkg := range pkgs {
|
|
docPkg := doc.New(pkg, dir, 0)
|
|
cleanedPkg := CopyPackage(docPkg)
|
|
pkgJSON, err := json.MarshalIndent(cleanedPkg, "", " ")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Printf("%s\n", pkgJSON)
|
|
}
|
|
}
|
|
}
|