Simplest working example of extracting Type names from given path of package

huangapple go评论62阅读模式
英文:

Simplest working example of extracting Type names from given path of package

问题

我是你的中文翻译助手,我会帮你翻译英文内容。以下是你要翻译的内容:

我对golang的AST包和相关的go工具(如astutils)还不太了解。目前我在理解Stringer示例并为自己的目的进行修改方面遇到了一些困难。

https://github.com/golang/tools/blob/master/cmd/stringer/stringer.go

是否有一个可以提取包路径中所有定义的类型名称列表的工作示例?

英文:

I'm new to golang AST package and related go tools like astutils. At the moment I'm a bit stucked in understanding the Stringer example and modifying it for my own purpose.

https://github.com/golang/tools/blob/master/cmd/stringer/stringer.go

Is there an working example of simply extract a list of all defined type names in a package path?

答案1

得分: 5

我想到了一个打印所有(顶层)类型名称的程序示例。解析目录,获取包并遍历它。

fs := token.NewFileSet()
pkgs, err := parser.ParseDir(fs, dir, nil, 0)
// 检查错误。
pkg, ok := pkgs["pkgname"]
// 检查是否成功。
ast.Walk(VisitorFunc(FindTypes), pkg)

其中VisitorFuncFindTypes定义如下:

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:
		fmt.Println(n.Name.Name)
	}
	return nil
}

完整代码请参考 Playground:http://play.golang.org/p/Rk_zmrmD0k(在那里无法工作,因为不允许进行文件系统操作)。


编辑: 这是一个在 Playground 上可以工作的版本,由评论中的 Ivan Black 提供:https://play.golang.org/p/yLV6-asPas

英文:

I've came up with this example of a program that prints all (top-level) type names. Parse the directory, get the package, and walk it.

fs := token.NewFileSet()
pkgs, err := parser.ParseDir(fs, dir, nil, 0)
// Check err.
pkg, ok := pkgs["pkgname"]
// Check ok.
ast.Walk(VisitorFunc(FindTypes), pkg)

Where VisitorFunc and FindTypes are defined as

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:
		fmt.Println(n.Name.Name)
	}
	return nil
}

Full code on Playground: http://play.golang.org/p/Rk_zmrmD0k (won't work there since the FS operations are disallowed).


EDIT: Here is a version that works on the Playground, by Ivan Black in the comments: https://play.golang.org/p/yLV6-asPas

huangapple
  • 本文由 发表于 2015年7月3日 19:32:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/31205830.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定