Il seguente test tenta di utilizzare AST per aggiungere campi a una struttura. I campi vengono aggiunti correttamente, ma i commenti vengono aggiunti fuori ordine. Ho capito che la posizione potrebbe dover essere specificata manualmente, ma finora ho trovato un vuoto trovando una risposta.Commenti fuori servizio dopo aver aggiunto l'articolo a Vai AST
Ecco un test in mancanza: http://play.golang.org/p/RID4N30FZK
Ecco il codice:
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)
}
Sospetto che sia necessario aggiornare la [Mappa commenti] (http://golang.org/pkg/go/ast/#NewCommentMap) affinché funzioni correttamente. –
Qui puoi vedere alcuni dettagli degli alberi effettivi e previsti: https://play.golang.org/p/qv63Hu1xmP grazie a https://golang.org/pkg/go/ast/#Fprint. Le principali differenze che vedo sono 'Slash',' NamePos' e 'Obj' non sono impostate. Ho provato a giocherellare con le posizioni, ma non sono riuscito a farlo bene ... – HectorJ
Questo mi ha bloccato ... Sembra che ci sia una sorta di altro tipo di bookeeping che deve essere fatto, dato che sono stato in grado di ottenere Slash e NamePos da abbinare (a prescindere dall'offset 100) in questo: http://play.golang.org/p/pQodZncMjA - e persino aggiungere Addline e CommentMap non sembrano aiutare: http: //play.golang. org/p/GGj2eDwDF- –