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:
Selene
2023-01-17 11:58:08 +01:00
committed by GitHub
co-authored by sam boyer
parent 9e097c531d
commit 68f1bfa471
9 changed files with 82 additions and 92 deletions
+5 -5
View File
@@ -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)
}
+2 -26
View File
@@ -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
View File
@@ -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 != "" {