From 4a41c4316f9a8e557f40aab8d6d4d90755fc2056 Mon Sep 17 00:00:00 2001 From: Chris Brand Date: Mon, 14 Oct 2024 09:56:27 +0200 Subject: [PATCH] Allow generic named types to be directly used as a provider (#22) * Allow generic named types to be directly used as a provider * Exclude testdata/ from coverage check --------- Co-authored-by: Chris Brand --- internal/template.go | 9 +++++++- internal/testdata/dev_exchange_graph.golden | 3 ++- .../testdata/dev_exchange_selected.golden | 1 + .../testdata/dev_exchange_specBack.golden | 2 +- internal/testdata/dev_exchange_tpldata.golden | 10 +++++++++ .../testdata/dev_exchange_weldoutput.golden | 21 ++++++++++++------- .../testdata/example/exchange/ops/backends.go | 5 +++++ .../testdata/example/exchange/state/adhoc.go | 8 +++++++ .../example/exchange/state/devstate/weld.go | 6 +++++- .../exchange/state/devstate/weld_gen.go | 21 ++++++++++++------- .../testdata/example/exchange/state/weld.go | 6 +++++- .../example/exchange/state/weld_gen.go | 17 ++++++++++----- internal/testdata/exchange_graph.golden | 3 ++- internal/testdata/exchange_selected.golden | 1 + internal/testdata/exchange_specBack.golden | 2 +- internal/testdata/exchange_tpldata.golden | 10 +++++++++ internal/testdata/exchange_weldoutput.golden | 17 ++++++++++----- sonar-project.properties | 2 +- 18 files changed, 112 insertions(+), 32 deletions(-) diff --git a/internal/template.go b/internal/template.go index da7643b..48213c9 100644 --- a/internal/template.go +++ b/internal/template.go @@ -313,7 +313,6 @@ func makeTypeRef(pkgCache *PkgCache, typ types.Type) (string, error) { } res := typ.String() - for _, pkg := range pkgs { if pkg.Path() == pkgCache.In { res = strings.ReplaceAll(res, pkg.Path()+".", "") @@ -554,6 +553,14 @@ func getTypePkgs(tl ...types.Type) ([]*types.Package, error) { if pkg != nil { pl = []*types.Package{pkg} } + + for i := 0; i < t.TypeArgs().Len(); i++ { + generics, err := getTypePkgs(t.TypeArgs().At(i)) + if err != nil { + return nil, err + } + pl = append(pl, generics...) + } case *types.Map: pl, err = getTypePkgs(t.Elem(), t.Key()) case *types.Signature: diff --git a/internal/testdata/dev_exchange_graph.golden b/internal/testdata/dev_exchange_graph.golden index 82f810d..6f1679e 100644 --- a/internal/testdata/dev_exchange_graph.golden +++ b/internal/testdata/dev_exchange_graph.golden @@ -1,4 +1,4 @@ -Set[10]: (inline) +Set[11]: (inline) Set[1]: var example/exchange/state.ChanProvider Func[1]: func example/exchange/state.NewModelChan() chan<- example/exchange.Model Set[9]: var example/backends/providers.WeldDev @@ -14,3 +14,4 @@ Set[10]: (inline) Func[1]: func example/external/mail.New(opts ...example/external/mail.option) (*example/external/mail.Mailer, error) Func[1]: func example/external/mail/mail.New() (*example/external/mail/mail.MailerLegacy, error) Func[1]: func example/external/versioned.New() *example/external/versioned/v1.Service + Func[1]: func example/exchange/state.NewGenericStringType() example/exchange/ops.TestFunc[example/exchange.Model, string] diff --git a/internal/testdata/dev_exchange_selected.golden b/internal/testdata/dev_exchange_selected.golden index ef906f0..ef6b93c 100644 --- a/internal/testdata/dev_exchange_selected.golden +++ b/internal/testdata/dev_exchange_selected.golden @@ -1,6 +1,7 @@ Func[1]: func example/exchange/db.Connect() (*example/exchange/db.ExchangeDB, error) Func[1]: func example/external/versioned.New() *example/external/versioned/v1.Service Func[1]: func example/exchange/state.NewModelChan() chan<- example/exchange.Model +Func[1]: func example/exchange/state.NewGenericStringType() example/exchange/ops.TestFunc[example/exchange.Model, string] Func[1]: func example/identity/email/client/dev.Make(b example/identity/email/client/logical.Backends) (example/identity/email.Client, error) Func[1]: func example/identity/users/client/dev.Make(b example/identity/users/client/logical.Backends) (example/identity/users.Client, error) Func[1]: func example/identity/email/db.Connect() (*example/identity/email/db.EmailDB, error) diff --git a/internal/testdata/dev_exchange_specBack.golden b/internal/testdata/dev_exchange_specBack.golden index 5ae030e..5b920a3 100644 --- a/internal/testdata/dev_exchange_specBack.golden +++ b/internal/testdata/dev_exchange_specBack.golden @@ -1 +1 @@ -example/exchange/ops.Backends[5]: *example/exchange/db.ExchangeDB, *example/external/versioned/v1.Service, chan<- example/exchange.Model, example/identity/email.Client, example/identity/users.Client +example/exchange/ops.Backends[6]: *example/exchange/db.ExchangeDB, *example/external/versioned/v1.Service, chan<- example/exchange.Model, example/exchange/ops.TestFunc[example/exchange.Model, string], example/identity/email.Client, example/identity/users.Client diff --git a/internal/testdata/dev_exchange_tpldata.golden b/internal/testdata/dev_exchange_tpldata.golden index 76c9e42..97217ca 100644 --- a/internal/testdata/dev_exchange_tpldata.golden +++ b/internal/testdata/dev_exchange_tpldata.golden @@ -92,6 +92,16 @@ deps: returnserr: true params: [] errwrapmsg: exchange db connect + - type: exchange_ops.TestFunc[exchange.Model, string] + var: genericStringFunc + getter: GenericStringFunc + isduplicate: false + provider: + funcpkg: exchange_state + funcname: NewGenericStringType + returnserr: false + params: [] + errwrapmsg: exchange state new generic string type - type: chan<- exchange.Model var: modelChan getter: ModelChan diff --git a/internal/testdata/dev_exchange_weldoutput.golden b/internal/testdata/dev_exchange_weldoutput.golden index abe6b89..72c8aae 100644 --- a/internal/testdata/dev_exchange_weldoutput.golden +++ b/internal/testdata/dev_exchange_weldoutput.golden @@ -42,6 +42,8 @@ func MakeBackends() (exchange_ops.Backends, error) { return nil, errors.Wrap(err, "exchange db connect") } + b.genericStringFunc = exchange_state.NewGenericStringType() + b.modelChan = exchange_state.NewModelChan() b.users, err = users_client_dev.Make(&b) @@ -60,13 +62,14 @@ func MakeBackends() (exchange_ops.Backends, error) { } type backendsImpl struct { - email email.Client - emailDB *email_db.EmailDB - exchangeDB *exchange_db.ExchangeDB - modelChan chan<- exchange.Model - users users.Client - usersDB *users_db.UsersDB - versioned *versioned_v1.Service + email email.Client + emailDB *email_db.EmailDB + exchangeDB *exchange_db.ExchangeDB + genericStringFunc exchange_ops.TestFunc[exchange.Model, string] + modelChan chan<- exchange.Model + users users.Client + usersDB *users_db.UsersDB + versioned *versioned_v1.Service } func (b *backendsImpl) Email() email.Client { @@ -81,6 +84,10 @@ func (b *backendsImpl) ExchangeDB() *exchange_db.ExchangeDB { return b.exchangeDB } +func (b *backendsImpl) GenericStringFunc() exchange_ops.TestFunc[exchange.Model, string] { + return b.genericStringFunc +} + func (b *backendsImpl) ModelChan() chan<- exchange.Model { return b.modelChan } diff --git a/internal/testdata/example/exchange/ops/backends.go b/internal/testdata/example/exchange/ops/backends.go index 8992a6d..bfbd279 100644 --- a/internal/testdata/example/exchange/ops/backends.go +++ b/internal/testdata/example/exchange/ops/backends.go @@ -8,7 +8,12 @@ import ( "example/identity/users" ) +type TestFunc[T any, C any] func(a T, c C) string + +type GenericStringType = TestFunc[exchange.Model, string] + type Backends interface { + GenericStringFunc() GenericStringType ExchangeDB() *db.ExchangeDB Email() email.Client Users() users.Client diff --git a/internal/testdata/example/exchange/state/adhoc.go b/internal/testdata/example/exchange/state/adhoc.go index 633dadc..3ddd438 100644 --- a/internal/testdata/example/exchange/state/adhoc.go +++ b/internal/testdata/example/exchange/state/adhoc.go @@ -2,7 +2,9 @@ package state import ( "example/exchange" + "fmt" + exchange_ops "example/exchange/ops" "github.com/luno/weld" ) @@ -11,3 +13,9 @@ var ChanProvider = weld.NewSet(NewModelChan) func NewModelChan() chan<- exchange.Model { return make(chan<- exchange.Model) } + +func NewGenericStringType() exchange_ops.GenericStringType { + return func(a exchange.Model, b string) string { + return fmt.Sprintf("%s%s", a, b) + } +} diff --git a/internal/testdata/example/exchange/state/devstate/weld.go b/internal/testdata/example/exchange/state/devstate/weld.go index 21a702a..02c9d2f 100644 --- a/internal/testdata/example/exchange/state/devstate/weld.go +++ b/internal/testdata/example/exchange/state/devstate/weld.go @@ -13,6 +13,10 @@ import ( //go:generate weld var _ = weld.NewSpec( - weld.NewSet(state.ChanProvider, providers.WeldDev), + weld.NewSet( + state.ChanProvider, + providers.WeldDev, + state.NewGenericStringType, + ), weld.Existing(new(exchange_ops.Backends)), ) diff --git a/internal/testdata/example/exchange/state/devstate/weld_gen.go b/internal/testdata/example/exchange/state/devstate/weld_gen.go index abe6b89..72c8aae 100644 --- a/internal/testdata/example/exchange/state/devstate/weld_gen.go +++ b/internal/testdata/example/exchange/state/devstate/weld_gen.go @@ -42,6 +42,8 @@ func MakeBackends() (exchange_ops.Backends, error) { return nil, errors.Wrap(err, "exchange db connect") } + b.genericStringFunc = exchange_state.NewGenericStringType() + b.modelChan = exchange_state.NewModelChan() b.users, err = users_client_dev.Make(&b) @@ -60,13 +62,14 @@ func MakeBackends() (exchange_ops.Backends, error) { } type backendsImpl struct { - email email.Client - emailDB *email_db.EmailDB - exchangeDB *exchange_db.ExchangeDB - modelChan chan<- exchange.Model - users users.Client - usersDB *users_db.UsersDB - versioned *versioned_v1.Service + email email.Client + emailDB *email_db.EmailDB + exchangeDB *exchange_db.ExchangeDB + genericStringFunc exchange_ops.TestFunc[exchange.Model, string] + modelChan chan<- exchange.Model + users users.Client + usersDB *users_db.UsersDB + versioned *versioned_v1.Service } func (b *backendsImpl) Email() email.Client { @@ -81,6 +84,10 @@ func (b *backendsImpl) ExchangeDB() *exchange_db.ExchangeDB { return b.exchangeDB } +func (b *backendsImpl) GenericStringFunc() exchange_ops.TestFunc[exchange.Model, string] { + return b.genericStringFunc +} + func (b *backendsImpl) ModelChan() chan<- exchange.Model { return b.modelChan } diff --git a/internal/testdata/example/exchange/state/weld.go b/internal/testdata/example/exchange/state/weld.go index d7e9c16..383b6dc 100644 --- a/internal/testdata/example/exchange/state/weld.go +++ b/internal/testdata/example/exchange/state/weld.go @@ -13,6 +13,10 @@ import ( // Note that github.com/luno/weld/internal/gen_test.go generates this specific state_gen.go as well. var _ = weld.NewSpec( - weld.NewSet(ChanProvider, providers.WeldProd), + weld.NewSet( + ChanProvider, + providers.WeldProd, + NewGenericStringType, + ), weld.Existing(new(exchange_ops.Backends)), ) diff --git a/internal/testdata/example/exchange/state/weld_gen.go b/internal/testdata/example/exchange/state/weld_gen.go index 2ce27a2..d2cd48f 100644 --- a/internal/testdata/example/exchange/state/weld_gen.go +++ b/internal/testdata/example/exchange/state/weld_gen.go @@ -34,6 +34,8 @@ func MakeBackends() (exchange_ops.Backends, error) { return nil, errors.Wrap(err, "exchange db connect") } + b.genericStringFunc = NewGenericStringType() + b.modelChan = NewModelChan() b.users, err = users_client_grpc.New() @@ -47,11 +49,12 @@ func MakeBackends() (exchange_ops.Backends, error) { } type backendsImpl struct { - email email.Client - exchangeDB *exchange_db.ExchangeDB - modelChan chan<- exchange.Model - users users.Client - versioned *versioned_v1.Service + email email.Client + exchangeDB *exchange_db.ExchangeDB + genericStringFunc exchange_ops.TestFunc[exchange.Model, string] + modelChan chan<- exchange.Model + users users.Client + versioned *versioned_v1.Service } func (b *backendsImpl) Email() email.Client { @@ -62,6 +65,10 @@ func (b *backendsImpl) ExchangeDB() *exchange_db.ExchangeDB { return b.exchangeDB } +func (b *backendsImpl) GenericStringFunc() exchange_ops.TestFunc[exchange.Model, string] { + return b.genericStringFunc +} + func (b *backendsImpl) ModelChan() chan<- exchange.Model { return b.modelChan } diff --git a/internal/testdata/exchange_graph.golden b/internal/testdata/exchange_graph.golden index 529c02d..0f6771b 100644 --- a/internal/testdata/exchange_graph.golden +++ b/internal/testdata/exchange_graph.golden @@ -1,4 +1,4 @@ -Set[13]: (inline) +Set[14]: (inline) Set[1]: var example/exchange/state.ChanProvider Func[1]: func example/exchange/state.NewModelChan() chan<- example/exchange.Model Set[12]: var example/backends/providers.WeldProd @@ -20,3 +20,4 @@ Set[13]: (inline) Func[1]: func example/external/mail.New(opts ...example/external/mail.option) (*example/external/mail.Mailer, error) Func[1]: func example/external/mail/mail.New() (*example/external/mail/mail.MailerLegacy, error) Func[1]: func example/external/versioned.New() *example/external/versioned/v1.Service + Func[1]: func example/exchange/state.NewGenericStringType() example/exchange/ops.TestFunc[example/exchange.Model, string] diff --git a/internal/testdata/exchange_selected.golden b/internal/testdata/exchange_selected.golden index cf8574e..c1340df 100644 --- a/internal/testdata/exchange_selected.golden +++ b/internal/testdata/exchange_selected.golden @@ -1,6 +1,7 @@ Func[1]: func example/exchange/db.Connect() (*example/exchange/db.ExchangeDB, error) Func[1]: func example/external/versioned.New() *example/external/versioned/v1.Service Func[1]: func example/exchange/state.NewModelChan() chan<- example/exchange.Model +Func[1]: func example/exchange/state.NewGenericStringType() example/exchange/ops.TestFunc[example/exchange.Model, string] Bind[1]: example/identity/email.Client(*example/identity/email/client/grpc.client) Bind[1]: example/identity/users.Client(*example/identity/users/client/grpc.client) Func[1]: func example/identity/email/client/grpc.New() (*example/identity/email/client/grpc.client, error) diff --git a/internal/testdata/exchange_specBack.golden b/internal/testdata/exchange_specBack.golden index 5ae030e..5b920a3 100644 --- a/internal/testdata/exchange_specBack.golden +++ b/internal/testdata/exchange_specBack.golden @@ -1 +1 @@ -example/exchange/ops.Backends[5]: *example/exchange/db.ExchangeDB, *example/external/versioned/v1.Service, chan<- example/exchange.Model, example/identity/email.Client, example/identity/users.Client +example/exchange/ops.Backends[6]: *example/exchange/db.ExchangeDB, *example/external/versioned/v1.Service, chan<- example/exchange.Model, example/exchange/ops.TestFunc[example/exchange.Model, string], example/identity/email.Client, example/identity/users.Client diff --git a/internal/testdata/exchange_tpldata.golden b/internal/testdata/exchange_tpldata.golden index 1767630..ec8d838 100644 --- a/internal/testdata/exchange_tpldata.golden +++ b/internal/testdata/exchange_tpldata.golden @@ -61,6 +61,16 @@ deps: returnserr: true params: [] errwrapmsg: exchange db connect + - type: exchange_ops.TestFunc[exchange.Model, string] + var: genericStringFunc + getter: GenericStringFunc + isduplicate: false + provider: + funcpkg: "" + funcname: NewGenericStringType + returnserr: false + params: [] + errwrapmsg: exchange state new generic string type - type: chan<- exchange.Model var: modelChan getter: ModelChan diff --git a/internal/testdata/exchange_weldoutput.golden b/internal/testdata/exchange_weldoutput.golden index 2ce27a2..d2cd48f 100644 --- a/internal/testdata/exchange_weldoutput.golden +++ b/internal/testdata/exchange_weldoutput.golden @@ -34,6 +34,8 @@ func MakeBackends() (exchange_ops.Backends, error) { return nil, errors.Wrap(err, "exchange db connect") } + b.genericStringFunc = NewGenericStringType() + b.modelChan = NewModelChan() b.users, err = users_client_grpc.New() @@ -47,11 +49,12 @@ func MakeBackends() (exchange_ops.Backends, error) { } type backendsImpl struct { - email email.Client - exchangeDB *exchange_db.ExchangeDB - modelChan chan<- exchange.Model - users users.Client - versioned *versioned_v1.Service + email email.Client + exchangeDB *exchange_db.ExchangeDB + genericStringFunc exchange_ops.TestFunc[exchange.Model, string] + modelChan chan<- exchange.Model + users users.Client + versioned *versioned_v1.Service } func (b *backendsImpl) Email() email.Client { @@ -62,6 +65,10 @@ func (b *backendsImpl) ExchangeDB() *exchange_db.ExchangeDB { return b.exchangeDB } +func (b *backendsImpl) GenericStringFunc() exchange_ops.TestFunc[exchange.Model, string] { + return b.genericStringFunc +} + func (b *backendsImpl) ModelChan() chan<- exchange.Model { return b.modelChan } diff --git a/sonar-project.properties b/sonar-project.properties index 6b49c02..a1aa429 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -4,7 +4,7 @@ sonar.projectName = weld sonar.links.scm = https://github.com/luno/weld sonar.sources = . -sonar.exclusions=**/*_test.go, **/*pb.go +sonar.exclusions=**/*_test.go, **/*pb.go, internal/testdata/** sonar.go.coverage.reportPaths = coverage.out sonar.go.tests.reportPaths = sonar-report.json sonar.tests = .