sphinx-autoapi/tests/goexample/example/godocjson.go
2015-06-10 11:04:19 -07:00

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)
}
}
}