Aşağıdaki sınama, bir yapıya alan eklemek için AST kullanmayı dener. Alanlar doğru şekilde eklenir, ancak yorumlar sırayla eklenir. Pozisyonu manuel olarak belirtmek zorunda kalabilirim, ama şimdiye kadar boş bir cevap buldum. İşte http://play.golang.org/p/RID4N30FZKYorumlar AST'ye öğe ekledikten sonra yapılan yorumlar yorumsuz: AST
kod::
İşte başarısız bir test var
package generator
import (
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"testing"
)
func TestAst(t *testing.T) {
source := `package a
// B comment
type B struct {
// C comment
C string
}`
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "", []byte(source), parser.ParseComments)
if err != nil {
t.Error(err)
}
v := &visitor{
file: file,
}
ast.Walk(v, file)
var output []byte
buf := bytes.NewBuffer(output)
if err := printer.Fprint(buf, fset, file); err != nil {
t.Error(err)
}
expected := `package a
// B comment
type B struct {
// C comment
C string
// D comment
D int
// E comment
E float64
}
`
if buf.String() != expected {
t.Error(fmt.Sprintf("Test failed. Expected:\n%s\nGot:\n%s", expected, buf.String()))
}
/*
actual output = `package a
// B comment
type B struct {
// C comment
// D comment
// E comment
C string
D int
E float64
}
`
*/
}
type visitor struct {
file *ast.File
}
func (v *visitor) Visit(node ast.Node) (w ast.Visitor) {
if node == nil {
return v
}
switch n := node.(type) {
case *ast.GenDecl:
if n.Tok != token.TYPE {
break
}
ts := n.Specs[0].(*ast.TypeSpec)
if ts.Name.Name == "B" {
fields := ts.Type.(*ast.StructType).Fields
addStructField(fields, v.file, "int", "D", "D comment")
addStructField(fields, v.file, "float64", "E", "E comment")
}
}
return v
}
func addStructField(fields *ast.FieldList, file *ast.File, typ string, name string, comment string) {
c := &ast.Comment{Text: fmt.Sprint("// ", comment)}
cg := &ast.CommentGroup{List: []*ast.Comment{c}}
f := &ast.Field{
Doc: cg,
Names: []*ast.Ident{ast.NewIdent(name)},
Type: ast.NewIdent(typ),
}
fields.List = append(fields.List, f)
file.Comments = append(file.Comments, cg)
}
Doğru çalışması için, [Yorum Haritası] 'nı (http://golang.org/pkg/go/ast/#NewCommentMap) güncellemeniz gerektiğinden şüpheleniyorum. –
Burada gerçek ve beklenen ağaçların bazı ayrıntılarını görebilirsiniz: https://play.golang.org/p/qv63Hu1xmP https://golang.org/pkg/go/ast/#Fprint. Gördüğüm en önemli farklar "Slash", "NamePos" ve "Obj" değerleri değil. Pozisyonlarla uğraşmaya çalıştım, ama doğru anlayamadım ... – HectorJ
Bu beni güldürdü ... Yapması gereken bir tür başka kitaplık var gibi görünüyor, Slash elde edebildiğim gibi ve NamePos (buna rağmen 100 ile dengelenerek): http://play.golang.org/p/pQodZncMjA - ve hatta AddLine ve CommentMap ekleyerek yardımcı olmuyor: http: //play.golang. org/p/GGj2eDwDF- –