Chore: Update ast to dst (#61469)
* Update ast to dst * Sort imports * Update thema * Update pkg/codegen/util_go.go Co-authored-by: sam boyer <sdboyer@grafana.com> * Move DecoderCompactor into ApplyFuncs * Remove unnecessary file * Use dst decorator * Downgrade parca-dev library Co-authored-by: sam boyer <sdboyer@grafana.com>
This commit is contained in:
@@ -2,13 +2,13 @@ package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"testing"
|
||||
|
||||
"github.com/dave/dst/decorator"
|
||||
"github.com/dave/dst/dstutil"
|
||||
"github.com/matryer/is"
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
)
|
||||
|
||||
func TestPrefixDropper(t *testing.T) {
|
||||
@@ -276,15 +276,15 @@ type Thing struct {
|
||||
}
|
||||
is := is.New(t)
|
||||
fset := token.NewFileSet()
|
||||
inf, err := parser.ParseFile(fset, "input.go", item.in, parser.ParseComments)
|
||||
inf, err := decorator.ParseFile(fset, "input.go", item.in, parser.ParseComments)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
drop := PrefixDropper("Foo")
|
||||
astutil.Apply(inf, drop, nil)
|
||||
dstutil.Apply(inf, drop, nil)
|
||||
buf := new(bytes.Buffer)
|
||||
err = format.Node(buf, fset, inf)
|
||||
err = decorator.Fprint(buf, inf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/dave/dst/decorator"
|
||||
"github.com/dave/dst/dstutil"
|
||||
"github.com/grafana/codejen"
|
||||
"github.com/grafana/thema/encoding/gocode"
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
)
|
||||
|
||||
// GoTypesJenny creates a [OneToOne] that produces Go types for the provided
|
||||
// [thema.Schema].
|
||||
type GoTypesJenny struct {
|
||||
ApplyFuncs []astutil.ApplyFunc
|
||||
ApplyFuncs []dstutil.ApplyFunc
|
||||
}
|
||||
|
||||
func (j GoTypesJenny) JennyName() string {
|
||||
@@ -25,32 +21,12 @@ func (j GoTypesJenny) Generate(sfg SchemaForGen) (*codejen.File, error) {
|
||||
b, err := gocode.GenerateTypesOpenAPI(sfg.Schema, &gocode.TypeConfigOpenAPI{
|
||||
// TODO will need to account for sanitizing e.g. dashes here at some point
|
||||
PackageName: sfg.Schema.Lineage().Name(),
|
||||
ApplyFuncs: append(j.ApplyFuncs, PrefixDropper(sfg.Name)),
|
||||
ApplyFuncs: append(j.ApplyFuncs, PrefixDropper(sfg.Name), DecoderCompactor()),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO switch to dst completely in thema so this can be made an ApplyFuncs element
|
||||
fb, err := decorator.Parse(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dstutil.Apply(fb, DecoderCompactor(), nil)
|
||||
buf := new(bytes.Buffer)
|
||||
err = decorator.Fprint(buf, fb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b, err = postprocessGoFile(genGoFile{
|
||||
path: "",
|
||||
walker: nil,
|
||||
in: buf.Bytes(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return codejen.NewFile(sfg.Schema.Lineage().Name()+"_types_gen.go", b, j), nil
|
||||
}
|
||||
|
||||
+36
-29
@@ -3,7 +3,6 @@ package codegen
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
@@ -13,14 +12,14 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/dave/dst"
|
||||
"github.com/dave/dst/decorator"
|
||||
"github.com/dave/dst/dstutil"
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
"golang.org/x/tools/imports"
|
||||
)
|
||||
|
||||
type genGoFile struct {
|
||||
path string
|
||||
walker astutil.ApplyFunc
|
||||
walker dstutil.ApplyFunc
|
||||
in []byte
|
||||
}
|
||||
|
||||
@@ -28,13 +27,13 @@ func postprocessGoFile(cfg genGoFile) ([]byte, error) {
|
||||
fname := filepath.Base(cfg.path)
|
||||
buf := new(bytes.Buffer)
|
||||
fset := token.NewFileSet()
|
||||
gf, err := parser.ParseFile(fset, fname, string(cfg.in), parser.ParseComments)
|
||||
gf, err := decorator.ParseFile(fset, fname, string(cfg.in), parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing generated file: %w", err)
|
||||
}
|
||||
|
||||
if cfg.walker != nil {
|
||||
astutil.Apply(gf, cfg.walker, nil)
|
||||
dstutil.Apply(gf, cfg.walker, nil)
|
||||
|
||||
err = format.Node(buf, fset, gf)
|
||||
if err != nil {
|
||||
@@ -77,10 +76,10 @@ type prefixmod struct {
|
||||
rxpsuff *regexp.Regexp
|
||||
}
|
||||
|
||||
// PrefixDropper returns an astutil.ApplyFunc that removes the provided prefix
|
||||
// PrefixDropper returns a dstutil.ApplyFunc that removes the provided prefix
|
||||
// string when it appears as a leading sequence in type names, var names, and
|
||||
// comments in a generated Go file.
|
||||
func PrefixDropper(prefix string) astutil.ApplyFunc {
|
||||
func PrefixDropper(prefix string) dstutil.ApplyFunc {
|
||||
return (&prefixmod{
|
||||
prefix: prefix,
|
||||
rxpsuff: regexp.MustCompile(fmt.Sprintf(`%s([a-zA-Z_]+)`, prefix)),
|
||||
@@ -88,13 +87,13 @@ func PrefixDropper(prefix string) astutil.ApplyFunc {
|
||||
}).applyfunc
|
||||
}
|
||||
|
||||
// PrefixReplacer returns an astutil.ApplyFunc that removes the provided prefix
|
||||
// PrefixReplacer returns a dstutil.ApplyFunc that removes the provided prefix
|
||||
// string when it appears as a leading sequence in type names, var names, and
|
||||
// comments in a generated Go file.
|
||||
//
|
||||
// When an exact match for prefix is found, the provided replace string
|
||||
// is substituted.
|
||||
func PrefixReplacer(prefix, replace string) astutil.ApplyFunc {
|
||||
func PrefixReplacer(prefix, replace string) dstutil.ApplyFunc {
|
||||
return (&prefixmod{
|
||||
prefix: prefix,
|
||||
replace: replace,
|
||||
@@ -103,62 +102,70 @@ func PrefixReplacer(prefix, replace string) astutil.ApplyFunc {
|
||||
}).applyfunc
|
||||
}
|
||||
|
||||
func depoint(e ast.Expr) ast.Expr {
|
||||
if star, is := e.(*ast.StarExpr); is {
|
||||
func depoint(e dst.Expr) dst.Expr {
|
||||
if star, is := e.(*dst.StarExpr); is {
|
||||
return star.X
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func (d prefixmod) applyfunc(c *astutil.Cursor) bool {
|
||||
func (d prefixmod) applyfunc(c *dstutil.Cursor) bool {
|
||||
n := c.Node()
|
||||
|
||||
switch x := n.(type) {
|
||||
case *ast.ValueSpec:
|
||||
case *dst.ValueSpec:
|
||||
d.handleExpr(x.Type)
|
||||
for _, id := range x.Names {
|
||||
d.do(id)
|
||||
}
|
||||
case *ast.TypeSpec:
|
||||
case *dst.TypeSpec:
|
||||
// Always do typespecs
|
||||
d.do(x.Name)
|
||||
case *ast.Field:
|
||||
case *dst.Field:
|
||||
// Don't rename struct fields. We just want to rename type declarations, and
|
||||
// field value specifications that reference those types.
|
||||
d.handleExpr(x.Type)
|
||||
|
||||
case *ast.CommentGroup:
|
||||
for _, c := range x.List {
|
||||
c.Text = d.rxpsuff.ReplaceAllString(c.Text, "$1")
|
||||
if d.replace != "" {
|
||||
c.Text = d.rxp.ReplaceAllString(c.Text, d.replace+"$1")
|
||||
case *dst.File:
|
||||
for _, decl := range x.Decls {
|
||||
comments := decl.Decorations().Start.All()
|
||||
decl.Decorations().Start.Clear()
|
||||
// For any reason, sometimes it retrieves the comment duplicated 🤷
|
||||
commentMap := make(map[string]bool)
|
||||
for _, c := range comments {
|
||||
if _, ok := commentMap[c]; !ok {
|
||||
commentMap[c] = true
|
||||
decl.Decorations().Start.Append(d.rxpsuff.ReplaceAllString(c, "$1"))
|
||||
if d.replace != "" {
|
||||
decl.Decorations().Start.Append(d.rxp.ReplaceAllString(c, d.replace+"$1"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (d prefixmod) handleExpr(e ast.Expr) {
|
||||
func (d prefixmod) handleExpr(e dst.Expr) {
|
||||
// Deref a StarExpr, if there is one
|
||||
expr := depoint(e)
|
||||
switch x := expr.(type) {
|
||||
case *ast.Ident:
|
||||
case *dst.Ident:
|
||||
d.do(x)
|
||||
case *ast.ArrayType:
|
||||
if id, is := depoint(x.Elt).(*ast.Ident); is {
|
||||
case *dst.ArrayType:
|
||||
if id, is := depoint(x.Elt).(*dst.Ident); is {
|
||||
d.do(id)
|
||||
}
|
||||
case *ast.MapType:
|
||||
if id, is := depoint(x.Key).(*ast.Ident); is {
|
||||
case *dst.MapType:
|
||||
if id, is := depoint(x.Key).(*dst.Ident); is {
|
||||
d.do(id)
|
||||
}
|
||||
if id, is := depoint(x.Value).(*ast.Ident); is {
|
||||
if id, is := depoint(x.Value).(*dst.Ident); is {
|
||||
d.do(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d prefixmod) do(n *ast.Ident) {
|
||||
func (d prefixmod) do(n *dst.Ident) {
|
||||
if n.Name != d.prefix {
|
||||
n.Name = strings.TrimPrefix(n.Name, d.prefix)
|
||||
} else if d.replace != "" {
|
||||
|
||||
Reference in New Issue
Block a user