I have folder with .go
files and functions defined inside them.
Is it possible to list in command line all function declarations in current folder, probably with godoc
?
godoc list functions /path/to/fileOrFolder
To have such output:
func Foo(a, b int) int
func Bar(c, d int) int
Definitely Peter's answer is very much sufficient, but if you want to go down the rabbit hole... and for the fun of it. Using powers of golang std lib ast.
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"log"
"os"
)
func main() {
// read file
// here you can filepath.Walk() for your go files
gopath := os.ExpandEnv("$GOPATH")
fname := gopath + "/src/github.com/golang/protobuf/proto/lib.go"
// read file
file, err := os.Open(fname)
if err != nil {
log.Println(err)
return
}
defer file.Close()
// read the whole file in
srcbuf, err := ioutil.ReadAll(file)
if err != nil {
log.Println(err)
return
}
src := string(srcbuf)
// file set
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "lib.go", src, 0)
if err != nil {
log.Println(err)
return
}
// main inspection
ast.Inspect(f, func(n ast.Node) bool {
switch fn := n.(type) {
// catching all function declarations
// other intersting things to catch FuncLit and FuncType
case *ast.FuncDecl:
fmt.Print("func ")
// if a method, explore and print receiver
if fn.Recv != nil {
fmt.Printf("(%s)", fields(*fn.Recv))
}
// print actual function name
fmt.Printf("%v", fn.Name)
// print function parameters
if fn.Type.Params != nil {
fmt.Printf("(%s)", fields(*fn.Type.Params))
}
// print return params
if fn.Type.Results != nil {
fmt.Printf("(%s)", fields(*fn.Type.Results))
}
fmt.Println()
}
return true
})
}
func expr(e ast.Expr) (ret string) {
switch x := e.(type) {
case *ast.StarExpr:
return fmt.Sprintf("%s*%v", ret, x.X)
case *ast.Ident:
return fmt.Sprintf("%s%v", ret, x.Name)
case *ast.ArrayType:
if x.Len != nil {
log.Println("OH OH looks like homework")
return "TODO: HOMEWORK"
}
res := expr(x.Elt)
return fmt.Sprintf("%s[]%v", ret, res)
case *ast.MapType:
return fmt.Sprintf("map[%s]%s", expr(x.Key), expr(x.Value))
case *ast.SelectorExpr:
return fmt.Sprintf("%s.%s", expr(x.X), expr(x.Sel))
default:
fmt.Printf("\nTODO HOMEWORK: %#v\n", x)
}
return
}
func fields(fl ast.FieldList) (ret string) {
pcomma := ""
for i, f := range fl.List {
// get all the names if present
var names string
ncomma := ""
for j, n := range f.Names {
if j > 0 {
ncomma = ", "
}
names = fmt.Sprintf("%s%s%s ", names, ncomma, n)
}
if i > 0 {
pcomma = ", "
}
ret = fmt.Sprintf("%s%s%s%s", ret, pcomma, names, expr(f.Type))
}
return ret
}
Building on @Peter's idea on an approach, you extract out all the exported functions using a simple grep + regex like this:
grep -rP '^func\s(?:\([^\)]+\)\s)?[A-Z].*' *.go
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With