diff --git a/Makefile b/Makefile index 11e99b5..314bef2 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ cover: fmt: goimports -l -w . - gofmt -l -w . dep: go get -u ./... \ No newline at end of file diff --git a/devpkg/deepcopygen/deepcopy.go b/devpkg/deepcopygen/deepcopy.go index fc7d0ef..7f216ec 100644 --- a/devpkg/deepcopygen/deepcopy.go +++ b/devpkg/deepcopygen/deepcopy.go @@ -3,6 +3,8 @@ package deepcopygen import ( "go/types" + "github.com/octohelm/gengo/devpkg/deepcopygen/helper" + "github.com/octohelm/gengo/pkg/gengo" ) @@ -99,106 +101,18 @@ func(in *@Type) DeepCopy() *@Type { } func(in *@Type) DeepCopyInto(out *@Type) { - @fieldCopies + @fieldsCopies } `, "Type": gengo.ID(named.Obj()), - "fieldCopies": func(sw gengo.SnippetWriter) { - for i := 0; i < x.NumFields(); i++ { - f := x.Field(i) - - ft := f.Type() - - switch x := ft.(type) { - case *types.Named: - inSamePkg := x.Obj().Pkg().Path() == named.Obj().Pkg().Path() - hasDeepCopy := false - hasDeepCopyInto := false - ptr := true - - for i := 0; i < x.NumMethods(); i++ { - m := x.Method(i) - fn := m.Type().(*types.Signature) - - // FIXME better check - hasDeepCopy = m.Name() == "DeepCopy" && fn.Results().Len() == 1 && fn.Params().Len() == 0 - hasDeepCopyInto = m.Name() == "DeepCopyInto" && fn.Params().Len() == 1 && fn.Results().Len() == 0 - - if hasDeepCopy { - if _, ok := fn.Results().At(0).Type().(*types.Pointer); !ok { - ptr = false - } - } - - if hasDeepCopyInto { - if _, ok := fn.Params().At(0).Type().(*types.Pointer); !ok { - ptr = false - } - } - } - - if inSamePkg { - defers = append(defers, x) - - // always gen - hasDeepCopyInto = true - hasDeepCopy = true - } - - if ptr && hasDeepCopyInto { - c.Render(gengo.Snippet{gengo.T: `in.@fieldName.DeepCopyInto(&out.@fieldName) -`, - "fieldName": gengo.ID(f.Name()), - }) - } else if !ptr && hasDeepCopy { - c.Render(gengo.Snippet{gengo.T: `out.@fieldName = in.@fieldName.DeepCopy() -`, - "fieldName": gengo.ID(f.Name()), - }) - } else if ptr && hasDeepCopy { - c.Render(gengo.Snippet{gengo.T: `out.@fieldName = *in.@fieldName.DeepCopy() -`, - "fieldName": gengo.ID(f.Name()), - }) - } else { - c.Render(gengo.Snippet{gengo.T: `out.@fieldName = in.@fieldName -`, - "fieldName": gengo.ID(f.Name()), - }) - } - case *types.Map: - c.Render(gengo.Snippet{gengo.T: ` -if in.@fieldName != nil { - i, o := &in.@fieldName, &out.@fieldName - *o = make(@MapType, len(*i)) - for key, val := range *i { - (*o)[key] = val - } -} -`, - "MapType": gengo.ID(x), - "fieldName": gengo.ID(f.Name()), - }) - case *types.Slice: - c.Render(gengo.Snippet{gengo.T: ` -if in.@fieldName != nil { - i, o := &in.@fieldName, &out.@fieldName - *o = make(@SliceType, len(*i)) - copy(*o, *i) -} -`, - "SliceType": gengo.ID(x), - "fieldName": gengo.ID(f.Name()), - }) - default: - c.Render(gengo.Snippet{gengo.T: ` -out.@fieldName = in.@fieldName -`, - "fieldName": gengo.ID(f.Name()), - }) - } - } - }, + "fieldsCopies": (&helper.StructFieldsCopy{ + Struct: x, + DeepCopyIntoName: "DeepCopyInto", + DeepCopyName: "DeepCopy", + OnLocalDep: func(named *types.Named) { + defers = append(defers, named) + }, + }).Snippet(c, named.Obj().Pkg()), }) default: c.Render(gengo.Snippet{gengo.T: ` diff --git a/devpkg/deepcopygen/helper/copy_fields.go b/devpkg/deepcopygen/helper/copy_fields.go new file mode 100644 index 0000000..0751a0f --- /dev/null +++ b/devpkg/deepcopygen/helper/copy_fields.go @@ -0,0 +1,154 @@ +package helper + +import ( + "fmt" + "go/types" + + "github.com/octohelm/gengo/pkg/gengo" +) + +type FieldContext struct { + InSamePkg bool + HasDeepCopy bool + HasDeepCopyInto bool + PtrResultOrParam bool +} + +type StructFieldsCopy struct { + DeepCopyName string + DeepCopyIntoName string + Struct *types.Struct + Skip func(f *types.Var) bool + OnLocalDep func(named *types.Named) + FieldContext func(f *types.Var) *FieldContext +} + +func (sfc *StructFieldsCopy) Snippet(c gengo.Context, pkg *types.Package) func(sw gengo.SnippetWriter) { + if sfc.DeepCopyName == "" { + sfc.DeepCopyName = "DeepCopy" + } + + if sfc.DeepCopyIntoName == "" { + sfc.DeepCopyIntoName = "DeepCopyInto" + } + + return func(sw gengo.SnippetWriter) { + for i := 0; i < sfc.Struct.NumFields(); i++ { + f := sfc.Struct.Field(i) + + if sfc.Skip != nil && sfc.Skip(f) { + continue + } + + fieldType := f.Type() + + switch x := fieldType.(type) { + case *types.Named: + if f.Name() == "Template" { + fmt.Println(x) + } + + var fc *FieldContext + + if sfc.FieldContext != nil { + if fcc := sfc.FieldContext(f); fcc != nil { + fc = fcc + } + } + + if fc == nil { + fc = &FieldContext{} + + fc.InSamePkg = x.Obj().Pkg().Path() == pkg.Path() + fc.PtrResultOrParam = true + + for i := 0; i < x.NumMethods(); i++ { + m := x.Method(i) + fn := m.Type().(*types.Signature) + + // FIXME better check + fc.HasDeepCopy = m.Name() == sfc.DeepCopyName && fn.Results().Len() == 1 && fn.Params().Len() == 0 + fc.HasDeepCopyInto = m.Name() == sfc.DeepCopyIntoName && fn.Params().Len() == 1 && fn.Results().Len() == 0 + + if fc.HasDeepCopy { + if _, ok := fn.Results().At(0).Type().(*types.Pointer); !ok { + fc.PtrResultOrParam = false + } + } + + if fc.HasDeepCopyInto { + if _, ok := fn.Params().At(0).Type().(*types.Pointer); !ok { + fc.PtrResultOrParam = false + } + } + } + } + + if fc.InSamePkg { + if sfc.OnLocalDep != nil { + sfc.OnLocalDep(x) + } + + // always gen + fc.HasDeepCopyInto = true + fc.HasDeepCopy = true + } + + if fc.PtrResultOrParam && fc.HasDeepCopyInto { + c.Render(gengo.Snippet{gengo.T: `in.@fieldName.@DeepCopyInto(&out.@fieldName) +`, + "fieldName": gengo.ID(f.Name()), + "DeepCopyInto": gengo.ID(sfc.DeepCopyIntoName), + }) + } else if !fc.PtrResultOrParam && fc.HasDeepCopy { + c.Render(gengo.Snippet{gengo.T: `out.@fieldName = in.@fieldName.@DeepCopy() +`, + "fieldName": gengo.ID(f.Name()), + "DeepCopy": gengo.ID(sfc.DeepCopyName), + }) + } else if fc.PtrResultOrParam && fc.HasDeepCopy { + c.Render(gengo.Snippet{gengo.T: `out.@fieldName = *in.@fieldName.@DeepCopy() +`, + "fieldName": gengo.ID(f.Name()), + "DeepCopy": gengo.ID(sfc.DeepCopyName), + }) + } else { + c.Render(gengo.Snippet{gengo.T: `out.@fieldName = in.@fieldName +`, + "fieldName": gengo.ID(f.Name()), + }) + } + case *types.Map: + c.Render(gengo.Snippet{gengo.T: ` +if in.@fieldName != nil { + i, o := &in.@fieldName, &out.@fieldName + *o = make(@MapType, len(*i)) + for key, val := range *i { + (*o)[key] = val + } +} +`, + "MapType": gengo.ID(x), + "fieldName": gengo.ID(f.Name()), + }) + case *types.Slice: + c.Render(gengo.Snippet{gengo.T: ` +if in.@fieldName != nil { + i, o := &in.@fieldName, &out.@fieldName + *o = make(@SliceType, len(*i)) + copy(*o, *i) +} +`, + "SliceType": gengo.ID(x), + "fieldName": gengo.ID(f.Name()), + }) + default: + c.Render(gengo.Snippet{gengo.T: ` +out.@fieldName = in.@fieldName +`, + "fieldName": gengo.ID(f.Name()), + }) + } + } + } +} diff --git a/devpkg/partialstruct/partialstruct.go b/devpkg/partialstruct/partialstruct.go new file mode 100644 index 0000000..b9b77c5 --- /dev/null +++ b/devpkg/partialstruct/partialstruct.go @@ -0,0 +1,186 @@ +package defaultergen + +import ( + "fmt" + "go/ast" + "go/types" + "strings" + + "github.com/octohelm/gengo/devpkg/deepcopygen/helper" + + "github.com/octohelm/gengo/pkg/gengo" + "github.com/pkg/errors" +) + +func init() { + gengo.Register(&partialStructGen{}) +} + +type partialStructGen struct{} + +func (*partialStructGen) Name() string { + return "partialstruct" +} + +func (g *partialStructGen) GenerateType(c gengo.Context, named *types.Named) error { + tags, _ := c.Doc(named.Obj()) + if !gengo.IsGeneratorEnabled(g, tags) { + return nil + } + + name := named.Obj().Name() + + ps := PartialStruct{ + Name: fmt.Sprintf("%s%s", strings.ToUpper(name[0:1]), name[1:]), + + Replace: map[string]string{}, + Omit: map[string]bool{}, + } + + if exclude, ok := tags["gengo:partialstruct:omit"]; ok { + for _, field := range exclude { + ps.Omit[field] = true + } + } + + if replace, ok := tags["gengo:partialstruct:replace"]; ok { + for _, field := range replace { + parts := strings.Split(field, ":") + if len(parts) == 2 { + ps.Replace[parts[0]] = parts[1] + } + } + } + + underlying := named.Underlying() + + ts, ok := underlying.(*types.Struct) + if !ok { + return errors.Errorf("must be struct type, but got %s", underlying) + } + + pkg := c.Package(named.Obj().Pkg().Path()) + decl := pkg.Decl(named.Obj().Pos()) + + if d, ok := decl.(*ast.GenDecl); ok { + for _, spec := range d.Specs { + switch x := spec.(type) { + case *ast.TypeSpec: + switch x := x.Type.(type) { + case *ast.Ident: + switch x := pkg.ObjectOf(x).(type) { + case *types.TypeName: + ps.Origin = x + } + case *ast.SelectorExpr: + switch x := pkg.ObjectOf(x.Sel).(type) { + case *types.TypeName: + ps.Origin = x + } + } + + } + } + } + + if ps.Origin == nil { + return errors.Errorf("need to define type like `type xxx sourcepkg.Type`") + } + + return ps.generate(c, named, ts) +} + +type PartialStruct struct { + Name string + Origin *types.TypeName + Omit map[string]bool + Replace map[string]string +} + +func (ps *PartialStruct) generate(c gengo.Context, named *types.Named, x *types.Struct) error { + c.Render(gengo.Snippet{ + gengo.T: ` +type @Type struct { + @fields +} + +func (in *@Type) DeepCopyAs() *@OriginType { + if in == nil { + return nil + } + out := new(@OriginType) + in.DeepCopyIntoAs(out) + return out +} + +func (in *@Type) DeepCopyIntoAs(out *@OriginType) { + @fieldsCopies +} +`, + "Type": gengo.ID(ps.Name), + "OriginType": gengo.ID(ps.Origin), + + "fieldsCopies": (&helper.StructFieldsCopy{ + DeepCopyIntoName: "DeepCopyIntoAs", + DeepCopyName: "DeepCopyAs", + Struct: x, + Skip: func(f *types.Var) bool { + return ps.Omit[f.Name()] + }, + FieldContext: func(f *types.Var) *helper.FieldContext { + if _, ok := ps.Replace[f.Name()]; ok { + fc := &helper.FieldContext{ + PtrResultOrParam: true, + HasDeepCopy: true, + HasDeepCopyInto: true, + } + + return fc + } + + return nil + }, + }).Snippet(c, named.Obj().Pkg()), + + "fields": func(sw gengo.SnippetWriter) { + + for i := 0; i < x.NumFields(); i++ { + f := x.Field(i) + tag := x.Tag(i) + fieldName := f.Name() + + if _, ok := ps.Omit[fieldName]; ok { + continue + } + + _, fieldDoc := c.Doc(f) + + if replaceTo, ok := ps.Replace[fieldName]; ok { + c.Render(gengo.Snippet{gengo.T: ` +@fieldDoc +@fieldName @fieldType ` + "`" + `@fieldTag` + "`" + ` +`, + "fieldDoc": gengo.Comment(strings.Join(fieldDoc, "\n")), + "fieldName": gengo.ID(fieldName), + "fieldType": gengo.ID(replaceTo), + "fieldTag": gengo.ID(tag), + }) + + continue + } + + c.Render(gengo.Snippet{gengo.T: ` +@fieldDoc +@fieldName @fieldType ` + "`" + `@fieldTag` + "`" + ` +`, + "fieldDoc": gengo.Comment(strings.Join(fieldDoc, "\n")), + "fieldName": gengo.ID(fieldName), + "fieldType": gengo.ID(f.Type()), + "fieldTag": gengo.ID(tag), + }) + } + }, + }) + + return nil +} diff --git a/devpkg/runtimedocgen/runtimedoc.go b/devpkg/runtimedocgen/runtimedoc.go index 903e83c..827f5de 100644 --- a/devpkg/runtimedocgen/runtimedoc.go +++ b/devpkg/runtimedocgen/runtimedoc.go @@ -1,10 +1,11 @@ package runtimedocgen import ( - "github.com/octohelm/gengo/pkg/gengo" - "github.com/pkg/errors" "go/ast" "go/types" + + "github.com/octohelm/gengo/pkg/gengo" + "github.com/pkg/errors" ) func init() { diff --git a/go.mod b/go.mod index aedac7f..462c54d 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,12 @@ go 1.22 require ( github.com/go-courier/logr v0.3.0 - github.com/octohelm/x v0.0.0-20240219080259-91528f21e203 - github.com/onsi/gomega v1.31.1 + github.com/octohelm/x v0.0.0-20240507072036-923e675e18dc + github.com/onsi/gomega v1.33.0 github.com/pkg/errors v0.9.1 golang.org/x/sync v0.7.0 - golang.org/x/text v0.14.0 - golang.org/x/tools v0.20.0 + golang.org/x/text v0.15.0 + golang.org/x/tools v0.21.0 ) require ( @@ -17,7 +17,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/net v0.25.0 // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index dc28e6e..cd33b4e 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/go-courier/logr v0.3.0 h1:0VEQB1b53EmYQ+ZehrIgD8l2IO+WX7TY+CqzlykIFmo= github.com/go-courier/logr v0.3.0/go.mod h1:OI7f/JCFZ1ZMD5qG3bIJr5WMNnGzd24+II1D9D9w5x4= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -15,26 +15,26 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/octohelm/x v0.0.0-20240219080259-91528f21e203 h1:ldyiEQngq5u7IajycYf35EUXeMDeYFtsjj2aEYTabsI= -github.com/octohelm/x v0.0.0-20240219080259-91528f21e203/go.mod h1:GgxRhMQ9rd89k19tCwS5f21SAxTS4ZR+9ZCYR13xXSo= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= -github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= +github.com/octohelm/x v0.0.0-20240507072036-923e675e18dc h1:iPCbeuhgkry0E/OGJImem5IgHNvn9flDOvh70mWlF0I= +github.com/octohelm/x v0.0.0-20240507072036-923e675e18dc/go.mod h1:Sbbekf0mbZbqc+uOokYMGus+35y30BAca0y0V58CyD0= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/gengo/context.go b/pkg/gengo/context.go index 876f5c5..026693d 100644 --- a/pkg/gengo/context.go +++ b/pkg/gengo/context.go @@ -2,16 +2,17 @@ package gengo import ( corecontext "context" - reflectx "github.com/octohelm/x/reflect" "go/token" "go/types" - "golang.org/x/sync/errgroup" "log/slog" "reflect" "sort" "strings" "sync" + reflectx "github.com/octohelm/x/reflect" + "golang.org/x/sync/errgroup" + "github.com/go-courier/logr" gengotypes "github.com/octohelm/gengo/pkg/types" "github.com/pkg/errors" diff --git a/pkg/namer/namer.go b/pkg/namer/namer.go index 1c893c7..2d9f7ad 100644 --- a/pkg/namer/namer.go +++ b/pkg/namer/namer.go @@ -1,9 +1,10 @@ package namer import ( - gengotypes "github.com/octohelm/gengo/pkg/types" "go/types" "strings" + + gengotypes "github.com/octohelm/gengo/pkg/types" ) type Namer interface { diff --git a/pkg/types/package.go b/pkg/types/package.go index e15df3e..e23c5ee 100644 --- a/pkg/types/package.go +++ b/pkg/types/package.go @@ -4,10 +4,11 @@ import ( "go/ast" "go/token" "go/types" - "golang.org/x/tools/go/packages" "path/filepath" "strings" "sync" + + "golang.org/x/tools/go/packages" ) type Module struct { @@ -26,14 +27,14 @@ type Package interface { SourceDir() string // Files ast files of package Files() []*ast.File + // Decl ast Decl for pos + Decl(pos token.Pos) ast.Decl // Doc comment tags and leading comments for pos Doc(pos token.Pos) (map[string][]string, []string) // Comment trailing comments for pos Comment(pos token.Pos) []string - // Eval eval expr in package Eval(expr ast.Expr) (types.TypeAndValue, error) - // Constant get constant by name Constant(name string) *types.Const // Constants get all constants of package @@ -320,6 +321,26 @@ func (pi *pkgInfo) Position(pos token.Pos) token.Position { return pi.Package.Fset.Position(pos) } +func (pi *pkgInfo) Decl(pos token.Pos) ast.Decl { + if f := pi.File(pos); f != nil { + for _, d := range f.Decls { + if d.Pos() <= pos && pos <= d.End() { + return d + } + } + } + return nil +} + +func (pi *pkgInfo) File(pos token.Pos) *ast.File { + for _, f := range pi.Files() { + if f.Pos() <= pos && pos <= f.End() { + return f + } + } + return nil +} + func (pi *pkgInfo) Doc(pos token.Pos) (map[string][]string, []string) { return ExtractCommentTags(commentLinesFrom(pi.priorCommentLines(pos, -1))) } diff --git a/testdata/a/b/zz_generated.defaulter.go b/testdata/a/b/zz_generated.defaulter.go index c6d2db7..da4afc6 100644 --- a/testdata/a/b/zz_generated.defaulter.go +++ b/testdata/a/b/zz_generated.defaulter.go @@ -1,5 +1,5 @@ /* -Package b GENERATED BY gengo:defaulter +Package b GENERATED BY gengo:defaulter DON'T EDIT THIS FILE */ package b diff --git a/testdata/a/b/zz_generated.runtimedoc.go b/testdata/a/b/zz_generated.runtimedoc.go index 9f69d5c..1ad706e 100644 --- a/testdata/a/b/zz_generated.runtimedoc.go +++ b/testdata/a/b/zz_generated.runtimedoc.go @@ -1,5 +1,5 @@ /* -Package b GENERATED BY gengo:runtimedoc +Package b GENERATED BY gengo:runtimedoc DON'T EDIT THIS FILE */ package b diff --git a/testdata/a/c/zz_generated.deepcopy.go b/testdata/a/c/zz_generated.deepcopy.go index cc86af7..0e844da 100644 --- a/testdata/a/c/zz_generated.deepcopy.go +++ b/testdata/a/c/zz_generated.deepcopy.go @@ -1,5 +1,5 @@ /* -Package c GENERATED BY gengo:deepcopy +Package c GENERATED BY gengo:deepcopy DON'T EDIT THIS FILE */ package c diff --git a/testdata/a/c/zz_generated.defaulter.go b/testdata/a/c/zz_generated.defaulter.go index 9bd7570..a79dd54 100644 --- a/testdata/a/c/zz_generated.defaulter.go +++ b/testdata/a/c/zz_generated.defaulter.go @@ -1,5 +1,5 @@ /* -Package c GENERATED BY gengo:defaulter +Package c GENERATED BY gengo:defaulter DON'T EDIT THIS FILE */ package c