当尝试使用 Go 的解析器和 ast 包提取与结构类型相关的文档注释时,找不到类型结构本身的注释。函数和字段的注释存在,但缺少名为 FirstType 和 SecondType 的类型的文档。
出现问题是因为 Go 解析器的默认解析行为不将文档注释与抽象语法树 (AST) 中的 TypeSpec 节点关联起来。当遇到 TypeSpec 时,解析器会消耗任何现有的 Doc 注释节点并将其从 AST 中删除。
使用纯 AST 解析注释
for _, f := range d { ast.Inspect(f, func(n ast.Node) bool { switch x := n.(type) { case *ast.FuncDecl: fmt.Printf("%s:\tFuncDecl %s\t%s\n", fset.Position(n.Pos()), x.Name, x.Doc.Text()) case *ast.TypeSpec: fmt.Printf("%s:\tTypeSpec %s\t%s\n", fset.Position(n.Pos()), x.Name, x.Doc.Text()) case *ast.Field: fmt.Printf("%s:\tField %s\t%s\n", fset.Position(n.Pos()), x.Names, x.Doc.Text()) case *ast.GenDecl: fmt.Printf("%s:\tGenDecl %s\n", fset.Position(n.Pos()), x.Doc.Text()) } return true }) }
添加案例用于 ast.GenDecl 到 AST 检查函数。这将检查与 GenDecl 节点关联的文档注释,这是在类型定义是多个单独定义的缩写的特殊情况下存储类型定义注释的位置。
但是,这种方法并不令人满意,因为文档注释不会附加到 AST 中相应的 TypeSpec 节点。
首选解决方案:使用 go/doc
import ( "go/doc" ) func main() { d, err := doc.ParseDir("./", nil, doc.AllDecls) if err != nil { fmt.Println(err) return } for _, info := range d { ast.Inspect(info.Decl, func(n ast.Node) bool { switch x := n.(type) { // ... inspecting cases for functions, fields, etc. case *ast.TypeSpec: fmt.Printf("%s:\tTypeSpec %s\t%s\n", fset.Position(n.Pos()), x.Name, info.Doc) } return true }) } }
使用 go/doc 提供了标准化且全面的解析和检索方法所有类型的文档注释,包括结构类型。它处理文档注释附加到 GenDecl 节点的情况,并确保注释与 AST 中相应节点的正确关联。
以上是为什么 Go 解析器无法检测类型结构的注释?的详细内容。更多信息请关注PHP中文网其他相关文章!