diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..00e992b --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module parse_go_project + +go 1.20 diff --git a/main.go b/main.go new file mode 100644 index 0000000..de3a65d --- /dev/null +++ b/main.go @@ -0,0 +1,165 @@ +package main + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" +) + +func main() { + fset := token.NewFileSet() + pkgs, err := parser.ParseDir(fset, "/home/eson/workspace/requests", nil, 0) + if err != nil { + fmt.Println(err) + return + } + + for _, pkg := range pkgs { + for fname, f := range pkg.Files { + fmt.Println("File:", fname) + ast.Inspect(f, func(n ast.Node) bool { + switch x := n.(type) { + case *ast.FuncDecl: + fmt.Printf(" Func: %v\n", x.Name.Name) + fmt.Printf(" Receiver: ") + if x.Recv != nil { + for _, l := range x.Recv.List { + fmt.Printf("%v ", l.Type) + } + } + fmt.Println() + fmt.Printf(" Params:") + if x.Type.Params != nil { + for _, f := range x.Type.Params.List { + for _, p := range f.Names { + fmt.Printf(" %s (%s)", p.Name, inspectExpr(f.Type)) + } + } + } + + fmt.Println() + fmt.Printf(" Results:") + if x.Type.Results != nil { + for _, f := range x.Type.Results.List { + fmt.Printf(" %v", f.Type) + } + fmt.Println() + } + + } + return true + }) + } + } +} + +func inspectExpr(n ast.Expr) string { + var s string + + switch x := n.(type) { + + case *ast.BadExpr: + s = fmt.Sprintf("From %v To %v", x.From, x.To) + + case *ast.Ident: + s = x.Name + + case *ast.Ellipsis: + s = inspectExpr(x.Elt) + + case *ast.BasicLit: + s = x.Value + + case *ast.FuncLit: + s = fmt.Sprintf("%#v", x) + + case *ast.CompositeLit: + s = fmt.Sprintf("%#v", x) + for _, elt := range x.Elts { + s += inspectExpr(elt) + } + + case *ast.ParenExpr: + s = inspectExpr(x.X) + + case *ast.SelectorExpr: + s = fmt.Sprintf("%s.%s", inspectExpr(x.X), x.Sel.Name) + + case *ast.IndexExpr: + s = inspectExpr(x.X) + + case *ast.IndexListExpr: + s = inspectExpr(x.X) + for _, index := range x.Indices { + s += inspectExpr(index) + } + + case *ast.SliceExpr: + s = inspectExpr(x.X) + + case *ast.TypeAssertExpr: + s = inspectExpr(x.X) + + case *ast.CallExpr: + s = inspectExpr(x.Fun) + for _, arg := range x.Args { + s += inspectExpr(arg) + } + + case *ast.StarExpr: + s = inspectExpr(x.X) + + case *ast.UnaryExpr: + s = inspectExpr(x.X) + + case *ast.BinaryExpr: + s = inspectExpr(x.X) + s += inspectExpr(x.Y) + + case *ast.KeyValueExpr: + s = fmt.Sprintf("%#v", inspectExpr(x.Key)) + s += inspectExpr(x.Value) + + case *ast.ArrayType: + s = fmt.Sprintf("%#v", x) + s += inspectExpr(x.Elt) + + case *ast.StructType: + s = fmt.Sprintf("%#v", x) + + case *ast.FuncType: + s = fmt.Sprintf("%#v", x) + if x.Params != nil { + for _, field := range x.Params.List { + s += inspectExpr(field.Type) + } + } + if x.Results != nil { + for _, field := range x.Results.List { + s += inspectExpr(field.Type) + } + } + + case *ast.InterfaceType: + s = fmt.Sprintf("%#v", x) + for _, field := range x.Methods.List { + s += inspectExpr(field.Type) + } + + case *ast.MapType: + s = fmt.Sprintf("%#v", x) + s += inspectExpr(x.Key) + s += inspectExpr(x.Value) + + case *ast.ChanType: + s = fmt.Sprintf("%#v", x) + s += inspectExpr(x.Value) + + default: + s = fmt.Sprintf("%T", n) + + } + + return s +} diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..ef64976 --- /dev/null +++ b/main_test.go @@ -0,0 +1,7 @@ +package main + +import "testing" + +func TestMain(t *testing.T) { + main() +}