猿问

如何在 AST 解析器中将类型解析为基元

我想提取函数的签名,以便能够在其上生成一些包装方法。为此,我正在使用它,它为我提供了阅读AST的可能性。golang.org/x/tools/go/packages

例如,对于函数定义,您会收到一些func MyFunc(param int)

ast.FuncDecl{
    Type: *FieldList{
        List: []*Field{
            {
                Names: []*Ident{ /*...*/ },
                Type:  nil, /*...*/
            },
        },
    },
}

其中“类型”表示类型。

我想为所有参数生成一些特殊代码,但int也可以用一些类型声明隐藏int

type MyType int

如何将类型转换为编译器具有的实际类型?ast


慕田峪9158850
浏览 98回答 1
1回答

largeQ

添加包。需求类型和包。需要类型信息到加载模式。这样,每个加载的包都将初始化其“类型信息”字段,并且该字段的类型为 *类型。“信息”有一个名为“类型”的字段,该字段将 ast 表达式映射到类型。您可以通过以下方式使用它:func main() {    loadConfig := new(packages.Config)    loadConfig.Mode = packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo    loadConfig.Fset = token.NewFileSet()    pkgs, err := packages.Load(loadConfig, "syscall")    if err != nil {        panic(err)    }    for _, pkg := range pkgs {        for _, syn := range pkg.Syntax {            for _, dec := range syn.Decls {                if fd, ok := dec.(*ast.FuncDecl); ok && fd.Name.Name == "Kill" {                    x1 := fd.Type.Params.List[0].Type // int                    x2 := fd.Type.Params.List[1].Type // syscall.Signal                    tv1 := pkg.TypesInfo.Types[x1]                    tv2 := pkg.TypesInfo.Types[x2]                    if basic, ok := tv1.Type.(*types.Basic); ok {                        fmt.Printf("%#v\n", basic) // int                    }                    if named, ok := tv2.Type.(*types.Named); ok {                        fmt.Printf("%v\n", named.Obj())         // *types.TypeName (Signal)                        fmt.Printf("%#v\n", named.Underlying()) // *types.Basic (int)                    }                }            }        }    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答