当我使用parser
包解析go源文件时,package xxx
语句被认为是普通的*ast.Ident
。有什么办法可以将其与其他声明区分开吗?还是在解析时优雅地忽略package语句?
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
}
答案 0 :(得分:0)
要跳过包标识符,应用程序必须编写代码以遍历* 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
函数。