當嘗試使用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中文網其他相關文章!