go - 当我通过解析器包解析 go 源文件时如何优雅地跳过包标识?
问题描述
当我用parser
包解析 go 源文件时,该package xxx
语句被认为是正常的*ast.Ident
. 有没有办法将它与其他声明区分开来?还是在解析时优雅地忽略包语句?
func walk(node ast.Node) bool {
switch n := node.(type) {
case *ast.File:
return true
case *ast.Ident:
// I want to check whether it is a package statement
case *ast.GenDecl:
return true
case *ast.TypeSpec:
return true
case *ast.StructType:
return true
case *ast.FieldList:
return true
case *ast.Field:
if len(n.Names) > 0 {
fmt.Println(n.Names[0].String())
}
default:
fmt.Printf("%T\n", node)
}
return false
}
func parseFile(filename string) error {
fs := token.NewFileSet()
f, err := parser.ParseFile(fs, filename, nil, parser.ParseComments)
if err != nil {
return err
}
ast.Inspect(f, walk)
return nil
}
解决方案
要跳过包标识符,应用程序必须编写代码来迭代 *ast.File 子项并跳过该代码中的包标识符:
func walk(node ast.Node) bool {
switch n := node.(type) {
case *ast.File:
walkFileNoPackageName(n)
// Return false to prevent caller from also
// walking children of n.
return false
... other cases as in question
func walkFileNoPackageName(n *ast.File) {
if n.Doc != nil {
ast.Inspect(n.Doc, walk)
}
// ast.Inspect(n.Name, walk) Skip over name
for _, x := range n.Decls {
ast.Inspect(x, walk)
}
}
如果您只对文件中的包级声明感兴趣,请从这些声明开始检查:
f, err := parser.ParseFile(fs, filename, nil, parser.ParseComments)
if err != nil {
return err
}
for _, n := range f.Decls {
ast.Inspect(n, walk)
}
按原样使用walk
问题中的功能。
推荐阅读
- python - 列表的随机值
- javascript - 列表中的 javascript link() 方法输出
- r - 如何将csv文件更改为栅格?
- python - 慢棋机器人,需要走得更快
- python - 如何根据 if else 语句数字条件在 Pandas 中获取新的输出数据帧
- javascript - 如何暂停渲染,直到在反应中获取数据
- android-recyclerview - RecyclerView 自定义 LayoutManager 移除不需要的视图
- mysql - MYSQL 中用户注册和第一次操作之间的平均时间
- flutter - 无法使用 SignalR 调用方法
- regex - 用于匹配类型注释的 Javascript 正则表达式