Następujący test próbuje użyć AST do dodania pól do struktury. Pola są dodawane poprawnie, ale komentarze są dodawane poza kolejnością. Zbieram pozycję, która może wymagać ręcznego określenia, ale do tej pory narysowałem pustkę znajdującą odpowiedź.Komentarze są nieczynne po dodaniu pozycji do wersji AST
Oto braku testu: http://play.golang.org/p/RID4N30FZK
Oto kod:
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)
}
Podejrzewam, że musisz zaktualizować [Comment Map] (http://golang.org/pkg/go/ast/#NewCommentMap), aby to działało poprawnie. –
Tutaj można zobaczyć niektóre szczegóły rzeczywistych i oczekiwanych drzew: https://play.golang.org/p/qv63Hu1xmP dzięki https://golang.org/pkg/go/ast/#Fprint. Główne różnice, które widzę, to 'Slash',' NamePos' i 'Obj' nie ustawione. Próbowałem skrzywdzić pozycje, ale nie mogłem tego naprawić ... – HectorJ
Ten mnie zaskoczył ... Wygląda na to, że trzeba coś zrobić, ponieważ udało mi się zdobyć Slasha i NamePos, aby dopasować (zrównoważyć o 100) w tym: http://play.golang.org/p/pQodZncMjA - a nawet dodanie w AddLine i CommentMap nie wydaje się pomóc: http: //play.golang. org/p/GGj2eDwDF- –