Skip to content

Instantly share code, notes, and snippets.

@awly
Last active December 17, 2015 08:59
Show Gist options
  • Save awly/5584150 to your computer and use it in GitHub Desktop.
Save awly/5584150 to your computer and use it in GitHub Desktop.
woah...
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
)
type TestStruct struct {
s string
a int
b error
c struct {
ca int
cb []byte
cc string
}
d []int
e map[string]uint
f interface{}
g func(int) error
h interface {
Print() string
}
j struct{}
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Must supply a file name to process.")
return
}
fset := token.NewFileSet()
f, err := parser.ParseFile(
fset,
os.Args[1],
nil,
0,
)
if err != nil {
fmt.Println(err)
return
}
for _, v := range f.Scope.Objects {
if v.Kind == ast.Typ {
spec := v.Decl.(*ast.TypeSpec)
fmt.Print(spec.Name, " ")
printType(spec.Type, true, 0)
}
}
}
func printType(t ast.Expr, cr bool, ident int) {
for i := 0; i < ident; i++ {
fmt.Print("\t")
}
switch typ := t.(type) {
case *ast.Ident:
fmt.Print(typ)
case *ast.ParenExpr:
printType(typ.X, cr, 0)
case *ast.SelectorExpr:
printType(typ.X, cr, 0)
fmt.Print("." + typ.Sel.String())
case *ast.StarExpr:
fmt.Print("*")
printType(typ.X, cr, 0)
case *ast.ArrayType:
fmt.Print("[")
if typ.Len != nil { //slice
fmt.Print(typ.Len)
}
fmt.Print("]")
printType(typ.Elt, false, 0)
case *ast.ChanType:
switch typ.Dir {
case ast.SEND:
fmt.Print("chan<- ")
case ast.RECV:
fmt.Print("<-chan ")
default:
fmt.Print("chan ")
}
printType(typ.Value, cr, 0)
case *ast.FuncType:
fmt.Print("func(")
if typ.Params != nil {
for _, pn := range typ.Params.List {
printType(pn.Type, false, 0)
}
}
fmt.Print(") ")
if typ.Results != nil {
fmt.Print("(")
for _, pn := range typ.Results.List {
printType(pn.Type, false, 0)
}
fmt.Print(")")
}
case *ast.InterfaceType:
fmt.Print("interface {")
if typ.Methods != nil && len(typ.Methods.List) != 0 {
fmt.Println()
for _, pn := range typ.Methods.List {
for i := 0; i < ident+1; i++ {
fmt.Print("\t")
}
fmt.Print(pn.Names[0])
printType(pn.Type, true, 1)
}
for i := 0; i < ident; i++ {
fmt.Print("\t")
}
}
fmt.Print("}")
case *ast.MapType:
fmt.Print("map[")
printType(typ.Key, false, 0)
fmt.Print("]")
printType(typ.Value, false, 0)
case *ast.StructType:
fmt.Print("struct {")
if typ.Fields != nil && len(typ.Fields.List) != 0 {
fmt.Println()
for _, pn := range typ.Fields.List {
for i := 0; i < ident+1; i++ {
fmt.Print("\t")
}
fmt.Print(pn.Names[0])
printType(pn.Type, true, 1)
}
for i := 0; i < ident; i++ {
fmt.Print("\t")
}
}
fmt.Print("}")
}
if cr {
fmt.Println()
}
}
TestStruct struct {
s string
a int
b error
c struct {
ca int
cb []byte
cc string
}
d []int
e map[string]uint
f interface {}
g func(int) (error)
h interface {
Print func() (string)
}
j struct {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment