首页  >  文章  >  后端开发  >  为什么 Go 解析器无法检测类型结构的注释?

为什么 Go 解析器无法检测类型结构的注释?

DDD
DDD原创
2024-11-07 02:49:03497浏览

Why Can't Go Parser Detect Comments on Type Structures?

Go 解析器未检测到类型结构上的注释

问题

当尝试使用 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn