dtj4307 2015-01-31 00:51
浏览 23
已采纳

如何解析方法声明?

I'm trying to parse a method declaration. Basically I need to get the syntax node of the receiver base type (type hello) and the return types (notype and error). The ast package seems straightforward but for some reason I don't get the data I need (i.e. the fields are reported nil).

The only useful data seems provided only in Object -> Decl field which is of type interface{} so I don't think I can serialize it.

Any help would be appreciated. Code below:

package main

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

func main() {
    // src is the input for which we want to inspect the AST.
    src := `
package mypack
// type hello is a cool type
type hello string

// type notype is not that cool
type notype int

// func printme is like nothing else.
func (x *hello)printme(s string)(notype, error){
    return 0, nil
}
`
    // Create the AST by parsing src.
    fset := token.NewFileSet() // positions are relative to fset
    f, err := parser.ParseFile(fset, "src.go", src, 0)
    if err != nil {
        panic(err)
    }

    // Inspect the AST and find our function
    var mf ast.FuncDecl
    ast.Inspect(f, func(n ast.Node) bool {
        switch x := n.(type) {
        case *ast.FuncDecl:
            mf = *x
        }
        return true
    })

    if mf.Recv != nil {
        fmt.Printf("
 receivers:")
        for _, v := range mf.Recv.List {
            fmt.Printf(",tag %v", v.Tag)
            for _, xv := range v.Names {
                fmt.Printf("name %v, decl %v, data %v, type %v",
                    xv.Name, xv.Obj.Decl, xv.Obj.Data, xv.Obj.Type)
            }
        }
    }
}

Playground

  • 写回答

1条回答 默认 最新

  • dousongqiang2585 2015-01-31 01:41
    关注

    To get the type you need to look at the Type attribute which could be an ast.StarExpr or an ast.Ident.

    Here take a look at this :

    package main
    
    import (
        "fmt"
        "go/ast"
        "go/parser"
        "go/token"
    )
    
    func main() {
        // src is the input for which we want to inspect the AST.
        src := `
    package mypack
    // type hello is a cool type
    type hello string
    
    // type notype is not that cool
    type notype int
    
    // printme is like nothing else.
    func (x *hello)printme(s string)(notype, error){
        return 0, nil
    }
    `
        // Create the AST by parsing src.
        fset := token.NewFileSet() // positions are relative to fset
        f, err := parser.ParseFile(fset, "src.go", src, 0)
        if err != nil {
            panic(err)
        }
    
        // Inspect the AST and find our function
        var mf ast.FuncDecl
        ast.Inspect(f, func(n ast.Node) bool {
            switch x := n.(type) {
            case *ast.FuncDecl:
                mf = *x
            }
            return true
        })
    
        if mf.Recv != nil {
            for _, v := range mf.Recv.List {
                fmt.Print("recv type : ")
                switch xv := v.Type.(type) {
                case *ast.StarExpr:
                    if si, ok := xv.X.(*ast.Ident); ok {
                        fmt.Println(si.Name)
                    }
                case *ast.Ident:
                    fmt.Println(xv.Name)
                }
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据