AST to parse contents of Structs

2,038 views
Skip to first unread message

Jeffrey Smith

unread,
Jan 27, 2017, 9:33:02 AM1/27/17
to golang-nuts
I'm trying to use the ast and parse packages to find the fields in two separate structs one that will be called Inputs and the other Outputs. these can change but as an example i'm trying to parse these

package main

import (
       "fmt"
)

type Inputs struct {
       Name string `json:"name"`
       Age  int    `json:"age"`
}

type Outputs struct {
       Number float `json:"number"`
}

func main() {

        fmt.Println("Hello World!")
}



I have the following which can pick out the two structs but i'm now lost on how to loop through the fields to get name, type and commenty bit `json:"name"` at the end. 

package main

import (
        "fmt"
        "go/ast"
        "go/parser"
        "go/token"
        "log"
)

func main() {

        fset := token.NewFileSet()
        file, err := parser.ParseFile(fset, "sample/main.go", nil, 0)
        if err != nil {
                log.Fatal(err)
        }
        ast.Walk(VisitorFunc(FindTypes), file)

}

type VisitorFunc func(n ast.Node) ast.Visitor

func (f VisitorFunc) Visit(n ast.Node) ast.Visitor {
        return f(n)
}

func FindTypes(n ast.Node) ast.Visitor {
        switch n := n.(type) {
        case *ast.Package:
                return VisitorFunc(FindTypes)
        case *ast.File:
                return VisitorFunc(FindTypes)
        case *ast.GenDecl:
                if n.Tok == token.TYPE {
                        return VisitorFunc(FindTypes)
                }
        case *ast.TypeSpec:
                if n.Name.Name == "Inputs" {
                        //We have hit the inputs struct
                        fmt.Println(n.Name.Name)
                }
                if n.Name.Name == "Outputs" {
                        //We have hit the outputs struct
                        fmt.Println(n.Name.Name)
                }
        }
        return nil
}

Any suggestions as to how to do it?

mhh...@gmail.com

unread,
Jan 29, 2017, 3:07:34 PM1/29/17
to golang-nuts
Hi,

maybe, should you load the program via the loader,
it helps a lot to deal with types relationships and many other things.
https://github.com/golang/example/tree/master/gotypes
https://godoc.org/golang.org/x/tools/go/loader

Now to understand the tree and understand it, I found this was useful,
https://gist.github.com/mh-cbon/3ed5d9c39e9635cfed0f896000098133

Its the same as https://golang.org/pkg/go/ast/#Print
but it won t print Object instance, making it clearer to read.
Object instance are not useful to understand the ast structure, in my understanding.

To get tag values, i guess you are looking for the Tag property of
https://golang.org/pkg/go/ast/#Field
Reply all
Reply to author
Forward
0 new messages