From 6f3e5ba4aa43024e945f20f6155d3068889d420d Mon Sep 17 00:00:00 2001 From: n0trace Date: Mon, 8 Aug 2022 15:58:16 +0800 Subject: [PATCH 1/2] support embedded generic interfaces --- mockgen/internal/tests/generics/external.go | 4 + mockgen/internal/tests/generics/generics.go | 7 + .../internal/tests/generics/other/other.go | 4 + .../generics/source/mock_external_test.go | 37 ++++ .../generics/source/mock_generics_test.go | 79 ++++++++ mockgen/parse.go | 185 ++++++++++-------- 6 files changed, 234 insertions(+), 82 deletions(-) diff --git a/mockgen/internal/tests/generics/external.go b/mockgen/internal/tests/generics/external.go index ec5032aa..bfad84e0 100644 --- a/mockgen/internal/tests/generics/external.go +++ b/mockgen/internal/tests/generics/external.go @@ -19,3 +19,7 @@ type ExternalConstraint[I constraints.Integer, F constraints.Float] interface { Nine(Iface[I]) Ten(*I) } + +type TwentyTwo[T any] interface { + TwentyTwo() T +} diff --git a/mockgen/internal/tests/generics/generics.go b/mockgen/internal/tests/generics/generics.go index 0b389622..b6f641e8 100644 --- a/mockgen/internal/tests/generics/generics.go +++ b/mockgen/internal/tests/generics/generics.go @@ -25,6 +25,13 @@ type Bar[T any, R any] interface { Seventeen() (*Foo[other.Three, other.Four], error) Eighteen() (Iface[*other.Five], error) Nineteen() AliasType + other.Twenty[T] + TwentyOne[T] + TwentyTwo[T] +} + +type TwentyOne[T any] interface { + TwentyOne() T } type Foo[T any, R any] struct{} diff --git a/mockgen/internal/tests/generics/other/other.go b/mockgen/internal/tests/generics/other/other.go index 9265422b..456b0ca9 100644 --- a/mockgen/internal/tests/generics/other/other.go +++ b/mockgen/internal/tests/generics/other/other.go @@ -9,3 +9,7 @@ type Three struct{} type Four struct{} type Five interface{} + +type Twenty[T any] interface { + Twenty() T +} diff --git a/mockgen/internal/tests/generics/source/mock_external_test.go b/mockgen/internal/tests/generics/source/mock_external_test.go index aab22749..178ac192 100644 --- a/mockgen/internal/tests/generics/source/mock_external_test.go +++ b/mockgen/internal/tests/generics/source/mock_external_test.go @@ -171,3 +171,40 @@ func (mr *MockExternalConstraintMockRecorder[I, F]) Two(arg0 interface{}) *gomoc mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Two", reflect.TypeOf((*MockExternalConstraint[I, F])(nil).Two), arg0) } + +// MockTwentyTwo is a mock of TwentyTwo interface. +type MockTwentyTwo[T any] struct { + ctrl *gomock.Controller + recorder *MockTwentyTwoMockRecorder[T] +} + +// MockTwentyTwoMockRecorder is the mock recorder for MockTwentyTwo. +type MockTwentyTwoMockRecorder[T any] struct { + mock *MockTwentyTwo[T] +} + +// NewMockTwentyTwo creates a new mock instance. +func NewMockTwentyTwo[T any](ctrl *gomock.Controller) *MockTwentyTwo[T] { + mock := &MockTwentyTwo[T]{ctrl: ctrl} + mock.recorder = &MockTwentyTwoMockRecorder[T]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTwentyTwo[T]) EXPECT() *MockTwentyTwoMockRecorder[T] { + return m.recorder +} + +// TwentyTwo mocks base method. +func (m *MockTwentyTwo[T]) TwentyTwo() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyTwo") + ret0, _ := ret[0].(T) + return ret0 +} + +// TwentyTwo indicates an expected call of TwentyTwo. +func (mr *MockTwentyTwoMockRecorder[T]) TwentyTwo() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyTwo", reflect.TypeOf((*MockTwentyTwo[T])(nil).TwentyTwo)) +} diff --git a/mockgen/internal/tests/generics/source/mock_generics_test.go b/mockgen/internal/tests/generics/source/mock_generics_test.go index 0223e311..aa3e4908 100644 --- a/mockgen/internal/tests/generics/source/mock_generics_test.go +++ b/mockgen/internal/tests/generics/source/mock_generics_test.go @@ -291,6 +291,48 @@ func (mr *MockBarMockRecorder[T, R]) Twelve() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Twelve", reflect.TypeOf((*MockBar[T, R])(nil).Twelve)) } +// Twenty mocks base method. +func (m *MockBar[T, R]) Twenty() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Twenty") + ret0, _ := ret[0].(T) + return ret0 +} + +// Twenty indicates an expected call of Twenty. +func (mr *MockBarMockRecorder[T, R]) Twenty() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Twenty", reflect.TypeOf((*MockBar[T, R])(nil).Twenty)) +} + +// TwentyOne mocks base method. +func (m *MockBar[T, R]) TwentyOne() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyOne") + ret0, _ := ret[0].(T) + return ret0 +} + +// TwentyOne indicates an expected call of TwentyOne. +func (mr *MockBarMockRecorder[T, R]) TwentyOne() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyOne", reflect.TypeOf((*MockBar[T, R])(nil).TwentyOne)) +} + +// TwentyTwo mocks base method. +func (m *MockBar[T, R]) TwentyTwo() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyTwo") + ret0, _ := ret[0].(T) + return ret0 +} + +// TwentyTwo indicates an expected call of TwentyTwo. +func (mr *MockBarMockRecorder[T, R]) TwentyTwo() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyTwo", reflect.TypeOf((*MockBar[T, R])(nil).TwentyTwo)) +} + // Two mocks base method. func (m *MockBar[T, R]) Two(arg0 T) string { m.ctrl.T.Helper() @@ -305,6 +347,43 @@ func (mr *MockBarMockRecorder[T, R]) Two(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Two", reflect.TypeOf((*MockBar[T, R])(nil).Two), arg0) } +// MockTwentyOne is a mock of TwentyOne interface. +type MockTwentyOne[T any] struct { + ctrl *gomock.Controller + recorder *MockTwentyOneMockRecorder[T] +} + +// MockTwentyOneMockRecorder is the mock recorder for MockTwentyOne. +type MockTwentyOneMockRecorder[T any] struct { + mock *MockTwentyOne[T] +} + +// NewMockTwentyOne creates a new mock instance. +func NewMockTwentyOne[T any](ctrl *gomock.Controller) *MockTwentyOne[T] { + mock := &MockTwentyOne[T]{ctrl: ctrl} + mock.recorder = &MockTwentyOneMockRecorder[T]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTwentyOne[T]) EXPECT() *MockTwentyOneMockRecorder[T] { + return m.recorder +} + +// TwentyOne mocks base method. +func (m *MockTwentyOne[T]) TwentyOne() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyOne") + ret0, _ := ret[0].(T) + return ret0 +} + +// TwentyOne indicates an expected call of TwentyOne. +func (mr *MockTwentyOneMockRecorder[T]) TwentyOne() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyOne", reflect.TypeOf((*MockTwentyOne[T])(nil).TwentyOne)) +} + // MockIface is a mock of Iface interface. type MockIface[T any] struct { ctrl *gomock.Controller diff --git a/mockgen/parse.go b/mockgen/parse.go index 21c0d70a..f2215d8c 100644 --- a/mockgen/parse.go +++ b/mockgen/parse.go @@ -288,106 +288,127 @@ func (p *fileParser) parseInterface(name, pkg string, it *namedInterface) (*mode } for _, field := range it.it.Methods.List { - switch v := field.Type.(type) { - case *ast.FuncType: - if nn := len(field.Names); nn != 1 { - return nil, fmt.Errorf("expected one name for interface %v, got %d", iface.Name, nn) - } - m := &model.Method{ - Name: field.Names[0].String(), - } + if err = p.parseField(field, field.Type, iface, pkg, tps); err != nil { + return nil, err + } + } + return iface, nil +} + +func (p *fileParser) parseField(field *ast.Field, fieldType ast.Expr, iface *model.Interface, pkg string, tps map[string]bool) error { + switch v := fieldType.(type) { + case *ast.FuncType: + if nn := len(field.Names); nn != 1 { + return fmt.Errorf("expected one name for interface %v, got %d", iface.Name, nn) + } + m := &model.Method{ + Name: field.Names[0].String(), + } + var err error + m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v, tps) + if err != nil { + return err + } + iface.AddMethod(m) + case *ast.Ident: + // Embedded interface in this package. + embeddedIfaceType := p.auxInterfaces.Get(pkg, v.String()) + if embeddedIfaceType == nil { + embeddedIfaceType = p.importedInterfaces.Get(pkg, v.String()) + } + + var embeddedIface *model.Interface + if embeddedIfaceType != nil { var err error - m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v, tps) + embeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType) if err != nil { - return nil, err - } - iface.AddMethod(m) - case *ast.Ident: - // Embedded interface in this package. - embeddedIfaceType := p.auxInterfaces.Get(pkg, v.String()) - if embeddedIfaceType == nil { - embeddedIfaceType = p.importedInterfaces.Get(pkg, v.String()) + return err } - - var embeddedIface *model.Interface - if embeddedIfaceType != nil { - var err error - embeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType) + } else { + // This is built-in error interface. + if v.String() == model.ErrorInterface.Name { + embeddedIface = &model.ErrorInterface + } else { + ip, err := p.parsePackage(pkg) if err != nil { - return nil, err + return p.errorf(v.Pos(), "could not parse package %s: %v", pkg, err) } - } else { - // This is built-in error interface. - if v.String() == model.ErrorInterface.Name { - embeddedIface = &model.ErrorInterface - } else { - ip, err := p.parsePackage(pkg) - if err != nil { - return nil, p.errorf(v.Pos(), "could not parse package %s: %v", pkg, err) - } - if embeddedIfaceType = ip.importedInterfaces.Get(pkg, v.String()); embeddedIfaceType == nil { - return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", pkg, v.String()) - } + if embeddedIfaceType = ip.importedInterfaces.Get(pkg, v.String()); embeddedIfaceType == nil { + return p.errorf(v.Pos(), "unknown embedded interface %s.%s", pkg, v.String()) + } - embeddedIface, err = ip.parseInterface(v.String(), pkg, embeddedIfaceType) - if err != nil { - return nil, err - } + embeddedIface, err = ip.parseInterface(v.String(), pkg, embeddedIfaceType) + if err != nil { + return err } } - // Copy the methods. - for _, m := range embeddedIface.Methods { - iface.AddMethod(m) - } - case *ast.SelectorExpr: - // Embedded interface in another package. - filePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() - embeddedPkg, ok := p.imports[filePkg] - if !ok { - return nil, p.errorf(v.X.Pos(), "unknown package %s", filePkg) - } + } + // Copy the methods. + for _, m := range embeddedIface.Methods { + iface.AddMethod(m) + } + case *ast.SelectorExpr: + // Embedded interface in another package. + filePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() + embeddedPkg, ok := p.imports[filePkg] + if !ok { + return p.errorf(v.X.Pos(), "unknown package %s", filePkg) + } - var embeddedIface *model.Interface - var err error - embeddedIfaceType := p.auxInterfaces.Get(filePkg, sel) - if embeddedIfaceType != nil { - embeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType) + var embeddedIface *model.Interface + var err error + embeddedIfaceType := p.auxInterfaces.Get(filePkg, sel) + if embeddedIfaceType != nil { + embeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType) + if err != nil { + return err + } + } else { + path := embeddedPkg.Path() + parser := embeddedPkg.Parser() + if parser == nil { + ip, err := p.parsePackage(path) if err != nil { - return nil, err - } - } else { - path := embeddedPkg.Path() - parser := embeddedPkg.Parser() - if parser == nil { - ip, err := p.parsePackage(path) - if err != nil { - return nil, p.errorf(v.Pos(), "could not parse package %s: %v", path, err) - } - parser = ip - p.imports[filePkg] = importedPkg{ - path: embeddedPkg.Path(), - parser: parser, - } + return p.errorf(v.Pos(), "could not parse package %s: %v", path, err) } - if embeddedIfaceType = parser.importedInterfaces.Get(path, sel); embeddedIfaceType == nil { - return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", path, sel) - } - embeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType) - if err != nil { - return nil, err + parser = ip + p.imports[filePkg] = importedPkg{ + path: embeddedPkg.Path(), + parser: parser, } } - // Copy the methods. - // TODO: apply shadowing rules. - for _, m := range embeddedIface.Methods { - iface.AddMethod(m) + if embeddedIfaceType = parser.importedInterfaces.Get(path, sel); embeddedIfaceType == nil { + return p.errorf(v.Pos(), "unknown embedded interface %s.%s", path, sel) + } + embeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType) + if err != nil { + return err + } + } + // Copy the methods. + // TODO: apply shadowing rules. + for _, m := range embeddedIface.Methods { + iface.AddMethod(m) + } + case *ast.IndexExpr: + switch vv := v.X.(type) { + case *ast.SelectorExpr: + if err := p.parseField(nil, vv, iface, pkg, tps); err != nil { + return err + } + case *ast.Ident: + if err := p.parseField(nil, vv, iface, pkg, tps); err != nil { + return err } default: - return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type) + return fmt.Errorf("don't know how to mock method of type %T", field.Type) } + + default: + return fmt.Errorf("don't know how to mock method of type %T", field.Type) } - return iface, nil + return nil } func (p *fileParser) parseFunc(pkg string, f *ast.FuncType, tps map[string]bool) (inParam []*model.Parameter, variadic *model.Parameter, outParam []*model.Parameter, err error) { From 27a536fc36826b22b31f27a9b6bae3127a20d6f0 Mon Sep 17 00:00:00 2001 From: n0trace Date: Fri, 12 Aug 2022 11:30:38 +0800 Subject: [PATCH 2/2] support embedded generic interfaces --- mockgen/generic_go118.go | 30 +- mockgen/generic_notgo118.go | 7 +- mockgen/internal/tests/generics/external.go | 49 +- mockgen/internal/tests/generics/generics.go | 12 +- .../internal/tests/generics/other/other.go | 10 +- .../tests/generics/source/assert_test.go | 12 + .../generics/source/mock_external_test.go | 562 +++++++++++++++++- .../generics/source/mock_generics_test.go | 113 ++-- mockgen/parse.go | 276 +++++---- 9 files changed, 861 insertions(+), 210 deletions(-) create mode 100644 mockgen/internal/tests/generics/source/assert_test.go diff --git a/mockgen/generic_go118.go b/mockgen/generic_go118.go index b29db9a8..26f5dffc 100644 --- a/mockgen/generic_go118.go +++ b/mockgen/generic_go118.go @@ -11,6 +11,7 @@ package main import ( + "fmt" "go/ast" "strings" @@ -24,7 +25,7 @@ func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field { return ts.TypeParams.List } -func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]bool) (model.Type, error) { +func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) { switch v := typ.(type) { case *ast.IndexExpr: m, err := p.parseType(pkg, v.X, tps) @@ -86,3 +87,30 @@ func getIdentTypeParams(decl interface{}) string { sb.WriteString("]") return sb.String() } + +func (p *fileParser) parseGenericMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) { + var indices []ast.Expr + var typ ast.Expr + switch v := field.Type.(type) { + case *ast.IndexExpr: + indices = []ast.Expr{v.Index} + typ = v.X + case *ast.IndexListExpr: + indices = v.Indices + typ = v.X + default: + return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type) + } + + nf := &ast.Field{ + Doc: field.Comment, + Names: field.Names, + Type: typ, + Tag: field.Tag, + Comment: field.Comment, + } + + it.embeddedInstTypeParams = indices + + return p.parseMethod(nf, it, iface, pkg, tps) +} diff --git a/mockgen/generic_notgo118.go b/mockgen/generic_notgo118.go index 8fe48c17..56304795 100644 --- a/mockgen/generic_notgo118.go +++ b/mockgen/generic_notgo118.go @@ -18,6 +18,7 @@ package main import ( + "fmt" "go/ast" "github.com/golang/mock/mockgen/model" @@ -27,10 +28,14 @@ func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field { return nil } -func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]bool) (model.Type, error) { +func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) { return nil, nil } func getIdentTypeParams(decl interface{}) string { return "" } + +func (p *fileParser) parseGenericMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) { + return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type) +} diff --git a/mockgen/internal/tests/generics/external.go b/mockgen/internal/tests/generics/external.go index bfad84e0..ecb355e0 100644 --- a/mockgen/internal/tests/generics/external.go +++ b/mockgen/internal/tests/generics/external.go @@ -1,6 +1,8 @@ package generics import ( + "context" + "github.com/golang/mock/mockgen/internal/tests/generics/other" "golang.org/x/exp/constraints" ) @@ -20,6 +22,49 @@ type ExternalConstraint[I constraints.Integer, F constraints.Float] interface { Ten(*I) } -type TwentyTwo[T any] interface { - TwentyTwo() T +type EmbeddingIface[T constraints.Integer, R constraints.Float] interface { + other.Twenty[T, StructType, R, other.Five] + TwentyTwo[StructType] + other.TwentyThree[TwentyTwo[R], TwentyTwo[T]] + TwentyFour[other.StructType] + Foo() error + ExternalConstraint[T, R] +} + +type TwentyOne[T any] interface { + TwentyOne() T +} + +type TwentyFour[T other.StructType] interface { + TwentyFour() T +} + +type Clonable[T any] interface { + Clone() T +} + +type Finder[T Clonable[T]] interface { + Find(ctx context.Context) ([]T, error) +} + +type UpdateNotifier[T any] interface { + NotifyC(ctx context.Context) <-chan []T + + Refresh(ctx context.Context) +} + +type EmbeddedW[W StructType] interface { + EmbeddedY[W] +} + +type EmbeddedX[X StructType] interface { + EmbeddedY[X] +} + +type EmbeddedY[Y StructType] interface { + EmbeddedZ[Y] +} + +type EmbeddedZ[Z any] interface { + EmbeddedZ(Z) } diff --git a/mockgen/internal/tests/generics/generics.go b/mockgen/internal/tests/generics/generics.go index b6f641e8..d0d02abe 100644 --- a/mockgen/internal/tests/generics/generics.go +++ b/mockgen/internal/tests/generics/generics.go @@ -25,13 +25,7 @@ type Bar[T any, R any] interface { Seventeen() (*Foo[other.Three, other.Four], error) Eighteen() (Iface[*other.Five], error) Nineteen() AliasType - other.Twenty[T] - TwentyOne[T] - TwentyTwo[T] -} - -type TwentyOne[T any] interface { - TwentyOne() T + other.Twenty[any, any, any, *other.Four] } type Foo[T any, R any] struct{} @@ -45,3 +39,7 @@ type StructType struct{} type StructType2 struct{} type AliasType Baz[other.Three] + +type TwentyTwo[T any] interface { + TwentyTwo() T +} diff --git a/mockgen/internal/tests/generics/other/other.go b/mockgen/internal/tests/generics/other/other.go index 456b0ca9..6129131b 100644 --- a/mockgen/internal/tests/generics/other/other.go +++ b/mockgen/internal/tests/generics/other/other.go @@ -10,6 +10,12 @@ type Four struct{} type Five interface{} -type Twenty[T any] interface { - Twenty() T +type Twenty[R, S, T any, Z any] interface { + Twenty(S, R) (T, Z) } + +type TwentyThree[U, V any] interface { + TwentyThree(U, V) StructType +} + +type StructType struct{} diff --git a/mockgen/internal/tests/generics/source/assert_test.go b/mockgen/internal/tests/generics/source/assert_test.go new file mode 100644 index 00000000..1168a418 --- /dev/null +++ b/mockgen/internal/tests/generics/source/assert_test.go @@ -0,0 +1,12 @@ +package source + +import ( + "testing" + + "github.com/golang/mock/mockgen/internal/tests/generics" +) + +func TestAssert(t *testing.T) { + var x MockEmbeddingIface[int, float64] + var _ generics.EmbeddingIface[int, float64] = &x +} diff --git a/mockgen/internal/tests/generics/source/mock_external_test.go b/mockgen/internal/tests/generics/source/mock_external_test.go index 178ac192..ab7f137a 100644 --- a/mockgen/internal/tests/generics/source/mock_external_test.go +++ b/mockgen/internal/tests/generics/source/mock_external_test.go @@ -5,6 +5,7 @@ package source import ( + context "context" reflect "reflect" gomock "github.com/golang/mock/gomock" @@ -172,39 +173,570 @@ func (mr *MockExternalConstraintMockRecorder[I, F]) Two(arg0 interface{}) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Two", reflect.TypeOf((*MockExternalConstraint[I, F])(nil).Two), arg0) } -// MockTwentyTwo is a mock of TwentyTwo interface. -type MockTwentyTwo[T any] struct { +// MockEmbeddingIface is a mock of EmbeddingIface interface. +type MockEmbeddingIface[T constraints.Integer, R constraints.Float] struct { ctrl *gomock.Controller - recorder *MockTwentyTwoMockRecorder[T] + recorder *MockEmbeddingIfaceMockRecorder[T, R] } -// MockTwentyTwoMockRecorder is the mock recorder for MockTwentyTwo. -type MockTwentyTwoMockRecorder[T any] struct { - mock *MockTwentyTwo[T] +// MockEmbeddingIfaceMockRecorder is the mock recorder for MockEmbeddingIface. +type MockEmbeddingIfaceMockRecorder[T constraints.Integer, R constraints.Float] struct { + mock *MockEmbeddingIface[T, R] } -// NewMockTwentyTwo creates a new mock instance. -func NewMockTwentyTwo[T any](ctrl *gomock.Controller) *MockTwentyTwo[T] { - mock := &MockTwentyTwo[T]{ctrl: ctrl} - mock.recorder = &MockTwentyTwoMockRecorder[T]{mock} +// NewMockEmbeddingIface creates a new mock instance. +func NewMockEmbeddingIface[T constraints.Integer, R constraints.Float](ctrl *gomock.Controller) *MockEmbeddingIface[T, R] { + mock := &MockEmbeddingIface[T, R]{ctrl: ctrl} + mock.recorder = &MockEmbeddingIfaceMockRecorder[T, R]{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockTwentyTwo[T]) EXPECT() *MockTwentyTwoMockRecorder[T] { +func (m *MockEmbeddingIface[T, R]) EXPECT() *MockEmbeddingIfaceMockRecorder[T, R] { return m.recorder } +// Eight mocks base method. +func (m *MockEmbeddingIface[T, R]) Eight(arg0 R) other.Two[T, R] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Eight", arg0) + ret0, _ := ret[0].(other.Two[T, R]) + return ret0 +} + +// Eight indicates an expected call of Eight. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Eight(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Eight", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Eight), arg0) +} + +// Five mocks base method. +func (m *MockEmbeddingIface[T, R]) Five(arg0 T) generics.Baz[R] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Five", arg0) + ret0, _ := ret[0].(generics.Baz[R]) + return ret0 +} + +// Five indicates an expected call of Five. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Five(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Five", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Five), arg0) +} + +// Foo mocks base method. +func (m *MockEmbeddingIface[T, R]) Foo() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Foo") + ret0, _ := ret[0].(error) + return ret0 +} + +// Foo indicates an expected call of Foo. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Foo() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Foo", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Foo)) +} + +// Four mocks base method. +func (m *MockEmbeddingIface[T, R]) Four(arg0 T) generics.Foo[T, R] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Four", arg0) + ret0, _ := ret[0].(generics.Foo[T, R]) + return ret0 +} + +// Four indicates an expected call of Four. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Four(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Four", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Four), arg0) +} + +// Nine mocks base method. +func (m *MockEmbeddingIface[T, R]) Nine(arg0 generics.Iface[T]) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Nine", arg0) +} + +// Nine indicates an expected call of Nine. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Nine(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Nine", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Nine), arg0) +} + +// One mocks base method. +func (m *MockEmbeddingIface[T, R]) One(arg0 string) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "One", arg0) + ret0, _ := ret[0].(string) + return ret0 +} + +// One indicates an expected call of One. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) One(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "One", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).One), arg0) +} + +// Seven mocks base method. +func (m *MockEmbeddingIface[T, R]) Seven(arg0 T) other.One[T] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Seven", arg0) + ret0, _ := ret[0].(other.One[T]) + return ret0 +} + +// Seven indicates an expected call of Seven. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Seven(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Seven", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Seven), arg0) +} + +// Six mocks base method. +func (m *MockEmbeddingIface[T, R]) Six(arg0 T) *generics.Baz[R] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Six", arg0) + ret0, _ := ret[0].(*generics.Baz[R]) + return ret0 +} + +// Six indicates an expected call of Six. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Six(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Six", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Six), arg0) +} + +// Ten mocks base method. +func (m *MockEmbeddingIface[T, R]) Ten(arg0 *T) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Ten", arg0) +} + +// Ten indicates an expected call of Ten. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Ten(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ten", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Ten), arg0) +} + +// Three mocks base method. +func (m *MockEmbeddingIface[T, R]) Three(arg0 T) R { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Three", arg0) + ret0, _ := ret[0].(R) + return ret0 +} + +// Three indicates an expected call of Three. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Three(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Three", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Three), arg0) +} + +// Twenty mocks base method. +func (m *MockEmbeddingIface[T, R]) Twenty(arg0 generics.StructType, arg1 T) (R, other.Five) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Twenty", arg0, arg1) + ret0, _ := ret[0].(R) + ret1, _ := ret[1].(other.Five) + return ret0, ret1 +} + +// Twenty indicates an expected call of Twenty. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Twenty(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Twenty", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Twenty), arg0, arg1) +} + +// TwentyFour mocks base method. +func (m *MockEmbeddingIface[T, R]) TwentyFour() other.StructType { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyFour") + ret0, _ := ret[0].(other.StructType) + return ret0 +} + +// TwentyFour indicates an expected call of TwentyFour. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) TwentyFour() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyFour", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).TwentyFour)) +} + +// TwentyThree mocks base method. +func (m *MockEmbeddingIface[T, R]) TwentyThree(arg0 generics.TwentyTwo[R], arg1 generics.TwentyTwo[T]) other.StructType { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyThree", arg0, arg1) + ret0, _ := ret[0].(other.StructType) + return ret0 +} + +// TwentyThree indicates an expected call of TwentyThree. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) TwentyThree(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyThree", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).TwentyThree), arg0, arg1) +} + // TwentyTwo mocks base method. -func (m *MockTwentyTwo[T]) TwentyTwo() T { +func (m *MockEmbeddingIface[T, R]) TwentyTwo() generics.StructType { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "TwentyTwo") - ret0, _ := ret[0].(T) + ret0, _ := ret[0].(generics.StructType) return ret0 } // TwentyTwo indicates an expected call of TwentyTwo. -func (mr *MockTwentyTwoMockRecorder[T]) TwentyTwo() *gomock.Call { +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) TwentyTwo() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyTwo", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).TwentyTwo)) +} + +// Two mocks base method. +func (m *MockEmbeddingIface[T, R]) Two(arg0 T) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Two", arg0) + ret0, _ := ret[0].(string) + return ret0 +} + +// Two indicates an expected call of Two. +func (mr *MockEmbeddingIfaceMockRecorder[T, R]) Two(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Two", reflect.TypeOf((*MockEmbeddingIface[T, R])(nil).Two), arg0) +} + +// MockTwentyOne is a mock of TwentyOne interface. +type MockTwentyOne[T any] struct { + ctrl *gomock.Controller + recorder *MockTwentyOneMockRecorder[T] +} + +// MockTwentyOneMockRecorder is the mock recorder for MockTwentyOne. +type MockTwentyOneMockRecorder[T any] struct { + mock *MockTwentyOne[T] +} + +// NewMockTwentyOne creates a new mock instance. +func NewMockTwentyOne[T any](ctrl *gomock.Controller) *MockTwentyOne[T] { + mock := &MockTwentyOne[T]{ctrl: ctrl} + mock.recorder = &MockTwentyOneMockRecorder[T]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTwentyOne[T]) EXPECT() *MockTwentyOneMockRecorder[T] { + return m.recorder +} + +// TwentyOne mocks base method. +func (m *MockTwentyOne[T]) TwentyOne() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyOne") + ret0, _ := ret[0].(T) + return ret0 +} + +// TwentyOne indicates an expected call of TwentyOne. +func (mr *MockTwentyOneMockRecorder[T]) TwentyOne() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyOne", reflect.TypeOf((*MockTwentyOne[T])(nil).TwentyOne)) +} + +// MockTwentyFour is a mock of TwentyFour interface. +type MockTwentyFour[T other.StructType] struct { + ctrl *gomock.Controller + recorder *MockTwentyFourMockRecorder[T] +} + +// MockTwentyFourMockRecorder is the mock recorder for MockTwentyFour. +type MockTwentyFourMockRecorder[T other.StructType] struct { + mock *MockTwentyFour[T] +} + +// NewMockTwentyFour creates a new mock instance. +func NewMockTwentyFour[T other.StructType](ctrl *gomock.Controller) *MockTwentyFour[T] { + mock := &MockTwentyFour[T]{ctrl: ctrl} + mock.recorder = &MockTwentyFourMockRecorder[T]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTwentyFour[T]) EXPECT() *MockTwentyFourMockRecorder[T] { + return m.recorder +} + +// TwentyFour mocks base method. +func (m *MockTwentyFour[T]) TwentyFour() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyFour") + ret0, _ := ret[0].(T) + return ret0 +} + +// TwentyFour indicates an expected call of TwentyFour. +func (mr *MockTwentyFourMockRecorder[T]) TwentyFour() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyFour", reflect.TypeOf((*MockTwentyFour[T])(nil).TwentyFour)) +} + +// MockClonable is a mock of Clonable interface. +type MockClonable[T any] struct { + ctrl *gomock.Controller + recorder *MockClonableMockRecorder[T] +} + +// MockClonableMockRecorder is the mock recorder for MockClonable. +type MockClonableMockRecorder[T any] struct { + mock *MockClonable[T] +} + +// NewMockClonable creates a new mock instance. +func NewMockClonable[T any](ctrl *gomock.Controller) *MockClonable[T] { + mock := &MockClonable[T]{ctrl: ctrl} + mock.recorder = &MockClonableMockRecorder[T]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClonable[T]) EXPECT() *MockClonableMockRecorder[T] { + return m.recorder +} + +// Clone mocks base method. +func (m *MockClonable[T]) Clone() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Clone") + ret0, _ := ret[0].(T) + return ret0 +} + +// Clone indicates an expected call of Clone. +func (mr *MockClonableMockRecorder[T]) Clone() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clone", reflect.TypeOf((*MockClonable[T])(nil).Clone)) +} + +// MockFinder is a mock of Finder interface. +type MockFinder[T generics.Clonable[T]] struct { + ctrl *gomock.Controller + recorder *MockFinderMockRecorder[T] +} + +// MockFinderMockRecorder is the mock recorder for MockFinder. +type MockFinderMockRecorder[T generics.Clonable[T]] struct { + mock *MockFinder[T] +} + +// NewMockFinder creates a new mock instance. +func NewMockFinder[T generics.Clonable[T]](ctrl *gomock.Controller) *MockFinder[T] { + mock := &MockFinder[T]{ctrl: ctrl} + mock.recorder = &MockFinderMockRecorder[T]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFinder[T]) EXPECT() *MockFinderMockRecorder[T] { + return m.recorder +} + +// Find mocks base method. +func (m *MockFinder[T]) Find(ctx context.Context) ([]T, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Find", ctx) + ret0, _ := ret[0].([]T) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Find indicates an expected call of Find. +func (mr *MockFinderMockRecorder[T]) Find(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Find", reflect.TypeOf((*MockFinder[T])(nil).Find), ctx) +} + +// MockUpdateNotifier is a mock of UpdateNotifier interface. +type MockUpdateNotifier[T any] struct { + ctrl *gomock.Controller + recorder *MockUpdateNotifierMockRecorder[T] +} + +// MockUpdateNotifierMockRecorder is the mock recorder for MockUpdateNotifier. +type MockUpdateNotifierMockRecorder[T any] struct { + mock *MockUpdateNotifier[T] +} + +// NewMockUpdateNotifier creates a new mock instance. +func NewMockUpdateNotifier[T any](ctrl *gomock.Controller) *MockUpdateNotifier[T] { + mock := &MockUpdateNotifier[T]{ctrl: ctrl} + mock.recorder = &MockUpdateNotifierMockRecorder[T]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockUpdateNotifier[T]) EXPECT() *MockUpdateNotifierMockRecorder[T] { + return m.recorder +} + +// NotifyC mocks base method. +func (m *MockUpdateNotifier[T]) NotifyC(ctx context.Context) <-chan []T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NotifyC", ctx) + ret0, _ := ret[0].(<-chan []T) + return ret0 +} + +// NotifyC indicates an expected call of NotifyC. +func (mr *MockUpdateNotifierMockRecorder[T]) NotifyC(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotifyC", reflect.TypeOf((*MockUpdateNotifier[T])(nil).NotifyC), ctx) +} + +// Refresh mocks base method. +func (m *MockUpdateNotifier[T]) Refresh(ctx context.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Refresh", ctx) +} + +// Refresh indicates an expected call of Refresh. +func (mr *MockUpdateNotifierMockRecorder[T]) Refresh(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Refresh", reflect.TypeOf((*MockUpdateNotifier[T])(nil).Refresh), ctx) +} + +// MockEmbeddedW is a mock of EmbeddedW interface. +type MockEmbeddedW[W generics.StructType] struct { + ctrl *gomock.Controller + recorder *MockEmbeddedWMockRecorder[W] +} + +// MockEmbeddedWMockRecorder is the mock recorder for MockEmbeddedW. +type MockEmbeddedWMockRecorder[W generics.StructType] struct { + mock *MockEmbeddedW[W] +} + +// NewMockEmbeddedW creates a new mock instance. +func NewMockEmbeddedW[W generics.StructType](ctrl *gomock.Controller) *MockEmbeddedW[W] { + mock := &MockEmbeddedW[W]{ctrl: ctrl} + mock.recorder = &MockEmbeddedWMockRecorder[W]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEmbeddedW[W]) EXPECT() *MockEmbeddedWMockRecorder[W] { + return m.recorder +} + +// EmbeddedZ mocks base method. +func (m *MockEmbeddedW[W]) EmbeddedZ(arg0 W) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "EmbeddedZ", arg0) +} + +// EmbeddedZ indicates an expected call of EmbeddedZ. +func (mr *MockEmbeddedWMockRecorder[W]) EmbeddedZ(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmbeddedZ", reflect.TypeOf((*MockEmbeddedW[W])(nil).EmbeddedZ), arg0) +} + +// MockEmbeddedX is a mock of EmbeddedX interface. +type MockEmbeddedX[X generics.StructType] struct { + ctrl *gomock.Controller + recorder *MockEmbeddedXMockRecorder[X] +} + +// MockEmbeddedXMockRecorder is the mock recorder for MockEmbeddedX. +type MockEmbeddedXMockRecorder[X generics.StructType] struct { + mock *MockEmbeddedX[X] +} + +// NewMockEmbeddedX creates a new mock instance. +func NewMockEmbeddedX[X generics.StructType](ctrl *gomock.Controller) *MockEmbeddedX[X] { + mock := &MockEmbeddedX[X]{ctrl: ctrl} + mock.recorder = &MockEmbeddedXMockRecorder[X]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEmbeddedX[X]) EXPECT() *MockEmbeddedXMockRecorder[X] { + return m.recorder +} + +// EmbeddedZ mocks base method. +func (m *MockEmbeddedX[X]) EmbeddedZ(arg0 X) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "EmbeddedZ", arg0) +} + +// EmbeddedZ indicates an expected call of EmbeddedZ. +func (mr *MockEmbeddedXMockRecorder[X]) EmbeddedZ(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmbeddedZ", reflect.TypeOf((*MockEmbeddedX[X])(nil).EmbeddedZ), arg0) +} + +// MockEmbeddedY is a mock of EmbeddedY interface. +type MockEmbeddedY[Y generics.StructType] struct { + ctrl *gomock.Controller + recorder *MockEmbeddedYMockRecorder[Y] +} + +// MockEmbeddedYMockRecorder is the mock recorder for MockEmbeddedY. +type MockEmbeddedYMockRecorder[Y generics.StructType] struct { + mock *MockEmbeddedY[Y] +} + +// NewMockEmbeddedY creates a new mock instance. +func NewMockEmbeddedY[Y generics.StructType](ctrl *gomock.Controller) *MockEmbeddedY[Y] { + mock := &MockEmbeddedY[Y]{ctrl: ctrl} + mock.recorder = &MockEmbeddedYMockRecorder[Y]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEmbeddedY[Y]) EXPECT() *MockEmbeddedYMockRecorder[Y] { + return m.recorder +} + +// EmbeddedZ mocks base method. +func (m *MockEmbeddedY[Y]) EmbeddedZ(arg0 Y) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "EmbeddedZ", arg0) +} + +// EmbeddedZ indicates an expected call of EmbeddedZ. +func (mr *MockEmbeddedYMockRecorder[Y]) EmbeddedZ(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmbeddedZ", reflect.TypeOf((*MockEmbeddedY[Y])(nil).EmbeddedZ), arg0) +} + +// MockEmbeddedZ is a mock of EmbeddedZ interface. +type MockEmbeddedZ[Z any] struct { + ctrl *gomock.Controller + recorder *MockEmbeddedZMockRecorder[Z] +} + +// MockEmbeddedZMockRecorder is the mock recorder for MockEmbeddedZ. +type MockEmbeddedZMockRecorder[Z any] struct { + mock *MockEmbeddedZ[Z] +} + +// NewMockEmbeddedZ creates a new mock instance. +func NewMockEmbeddedZ[Z any](ctrl *gomock.Controller) *MockEmbeddedZ[Z] { + mock := &MockEmbeddedZ[Z]{ctrl: ctrl} + mock.recorder = &MockEmbeddedZMockRecorder[Z]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEmbeddedZ[Z]) EXPECT() *MockEmbeddedZMockRecorder[Z] { + return m.recorder +} + +// EmbeddedZ mocks base method. +func (m *MockEmbeddedZ[Z]) EmbeddedZ(arg0 Z) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "EmbeddedZ", arg0) +} + +// EmbeddedZ indicates an expected call of EmbeddedZ. +func (mr *MockEmbeddedZMockRecorder[Z]) EmbeddedZ(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyTwo", reflect.TypeOf((*MockTwentyTwo[T])(nil).TwentyTwo)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmbeddedZ", reflect.TypeOf((*MockEmbeddedZ[Z])(nil).EmbeddedZ), arg0) } diff --git a/mockgen/internal/tests/generics/source/mock_generics_test.go b/mockgen/internal/tests/generics/source/mock_generics_test.go index aa3e4908..5207636f 100644 --- a/mockgen/internal/tests/generics/source/mock_generics_test.go +++ b/mockgen/internal/tests/generics/source/mock_generics_test.go @@ -292,45 +292,18 @@ func (mr *MockBarMockRecorder[T, R]) Twelve() *gomock.Call { } // Twenty mocks base method. -func (m *MockBar[T, R]) Twenty() T { +func (m *MockBar[T, R]) Twenty(arg0, arg1 any) (any, *other.Four) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Twenty") - ret0, _ := ret[0].(T) - return ret0 + ret := m.ctrl.Call(m, "Twenty", arg0, arg1) + ret0, _ := ret[0].(any) + ret1, _ := ret[1].(*other.Four) + return ret0, ret1 } // Twenty indicates an expected call of Twenty. -func (mr *MockBarMockRecorder[T, R]) Twenty() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Twenty", reflect.TypeOf((*MockBar[T, R])(nil).Twenty)) -} - -// TwentyOne mocks base method. -func (m *MockBar[T, R]) TwentyOne() T { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TwentyOne") - ret0, _ := ret[0].(T) - return ret0 -} - -// TwentyOne indicates an expected call of TwentyOne. -func (mr *MockBarMockRecorder[T, R]) TwentyOne() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyOne", reflect.TypeOf((*MockBar[T, R])(nil).TwentyOne)) -} - -// TwentyTwo mocks base method. -func (m *MockBar[T, R]) TwentyTwo() T { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TwentyTwo") - ret0, _ := ret[0].(T) - return ret0 -} - -// TwentyTwo indicates an expected call of TwentyTwo. -func (mr *MockBarMockRecorder[T, R]) TwentyTwo() *gomock.Call { +func (mr *MockBarMockRecorder[T, R]) Twenty(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyTwo", reflect.TypeOf((*MockBar[T, R])(nil).TwentyTwo)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Twenty", reflect.TypeOf((*MockBar[T, R])(nil).Twenty), arg0, arg1) } // Two mocks base method. @@ -347,62 +320,62 @@ func (mr *MockBarMockRecorder[T, R]) Two(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Two", reflect.TypeOf((*MockBar[T, R])(nil).Two), arg0) } -// MockTwentyOne is a mock of TwentyOne interface. -type MockTwentyOne[T any] struct { +// MockIface is a mock of Iface interface. +type MockIface[T any] struct { ctrl *gomock.Controller - recorder *MockTwentyOneMockRecorder[T] + recorder *MockIfaceMockRecorder[T] } -// MockTwentyOneMockRecorder is the mock recorder for MockTwentyOne. -type MockTwentyOneMockRecorder[T any] struct { - mock *MockTwentyOne[T] +// MockIfaceMockRecorder is the mock recorder for MockIface. +type MockIfaceMockRecorder[T any] struct { + mock *MockIface[T] } -// NewMockTwentyOne creates a new mock instance. -func NewMockTwentyOne[T any](ctrl *gomock.Controller) *MockTwentyOne[T] { - mock := &MockTwentyOne[T]{ctrl: ctrl} - mock.recorder = &MockTwentyOneMockRecorder[T]{mock} +// NewMockIface creates a new mock instance. +func NewMockIface[T any](ctrl *gomock.Controller) *MockIface[T] { + mock := &MockIface[T]{ctrl: ctrl} + mock.recorder = &MockIfaceMockRecorder[T]{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockTwentyOne[T]) EXPECT() *MockTwentyOneMockRecorder[T] { +func (m *MockIface[T]) EXPECT() *MockIfaceMockRecorder[T] { return m.recorder } -// TwentyOne mocks base method. -func (m *MockTwentyOne[T]) TwentyOne() T { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TwentyOne") - ret0, _ := ret[0].(T) - return ret0 -} - -// TwentyOne indicates an expected call of TwentyOne. -func (mr *MockTwentyOneMockRecorder[T]) TwentyOne() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyOne", reflect.TypeOf((*MockTwentyOne[T])(nil).TwentyOne)) -} - -// MockIface is a mock of Iface interface. -type MockIface[T any] struct { +// MockTwentyTwo is a mock of TwentyTwo interface. +type MockTwentyTwo[T any] struct { ctrl *gomock.Controller - recorder *MockIfaceMockRecorder[T] + recorder *MockTwentyTwoMockRecorder[T] } -// MockIfaceMockRecorder is the mock recorder for MockIface. -type MockIfaceMockRecorder[T any] struct { - mock *MockIface[T] +// MockTwentyTwoMockRecorder is the mock recorder for MockTwentyTwo. +type MockTwentyTwoMockRecorder[T any] struct { + mock *MockTwentyTwo[T] } -// NewMockIface creates a new mock instance. -func NewMockIface[T any](ctrl *gomock.Controller) *MockIface[T] { - mock := &MockIface[T]{ctrl: ctrl} - mock.recorder = &MockIfaceMockRecorder[T]{mock} +// NewMockTwentyTwo creates a new mock instance. +func NewMockTwentyTwo[T any](ctrl *gomock.Controller) *MockTwentyTwo[T] { + mock := &MockTwentyTwo[T]{ctrl: ctrl} + mock.recorder = &MockTwentyTwoMockRecorder[T]{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIface[T]) EXPECT() *MockIfaceMockRecorder[T] { +func (m *MockTwentyTwo[T]) EXPECT() *MockTwentyTwoMockRecorder[T] { return m.recorder } + +// TwentyTwo mocks base method. +func (m *MockTwentyTwo[T]) TwentyTwo() T { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TwentyTwo") + ret0, _ := ret[0].(T) + return ret0 +} + +// TwentyTwo indicates an expected call of TwentyTwo. +func (mr *MockTwentyTwoMockRecorder[T]) TwentyTwo() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TwentyTwo", reflect.TypeOf((*MockTwentyTwo[T])(nil).TwentyTwo)) +} diff --git a/mockgen/parse.go b/mockgen/parse.go index f2215d8c..59622d89 100644 --- a/mockgen/parse.go +++ b/mockgen/parse.go @@ -274,144 +274,191 @@ func (p *fileParser) parsePackage(path string) (*fileParser, error) { return newP, nil } +func (p *fileParser) constructInstParams(pkg string, params []*ast.Field, instParams []model.Type, embeddedInstParams []ast.Expr, tps map[string]model.Type) ([]model.Type, error) { + pm := make(map[string]int) + var i int + for _, v := range params { + for _, n := range v.Names { + pm[n.Name] = i + instParams = append(instParams, model.PredeclaredType(n.Name)) + i++ + } + } + + var runtimeInstParams []model.Type + for _, instParam := range embeddedInstParams { + switch t := instParam.(type) { + case *ast.Ident: + if idx, ok := pm[t.Name]; ok { + runtimeInstParams = append(runtimeInstParams, instParams[idx]) + continue + } + } + modelType, err := p.parseType(pkg, instParam, tps) + if err != nil { + return nil, err + } + runtimeInstParams = append(runtimeInstParams, modelType) + } + + return runtimeInstParams, nil +} + +func (p *fileParser) constructTps(it *namedInterface) (tps map[string]model.Type) { + tps = make(map[string]model.Type) + n := 0 + for _, tp := range it.typeParams { + for _, tm := range tp.Names { + tps[tm.Name] = nil + if len(it.instTypes) != 0 { + tps[tm.Name] = it.instTypes[n] + n++ + } + } + } + return tps +} + +// parseInterface loads interface specified by pkg and name, parses it and returns +// a new model with the parsed. func (p *fileParser) parseInterface(name, pkg string, it *namedInterface) (*model.Interface, error) { iface := &model.Interface{Name: name} - tps := make(map[string]bool) - + tps := p.constructTps(it) tp, err := p.parseFieldList(pkg, it.typeParams, tps) if err != nil { return nil, fmt.Errorf("unable to parse interface type parameters: %v", name) } - iface.TypeParams = tp - for _, v := range tp { - tps[v.Name] = true - } + iface.TypeParams = tp for _, field := range it.it.Methods.List { - if err = p.parseField(field, field.Type, iface, pkg, tps); err != nil { + var methods []*model.Method + if methods, err = p.parseMethod(field, it, iface, pkg, tps); err != nil { return nil, err } + for _, m := range methods { + iface.AddMethod(m) + } } return iface, nil } -func (p *fileParser) parseField(field *ast.Field, fieldType ast.Expr, iface *model.Interface, pkg string, tps map[string]bool) error { - switch v := fieldType.(type) { - case *ast.FuncType: - if nn := len(field.Names); nn != 1 { - return fmt.Errorf("expected one name for interface %v, got %d", iface.Name, nn) - } - m := &model.Method{ - Name: field.Names[0].String(), - } - var err error - m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v, tps) - if err != nil { - return err - } - iface.AddMethod(m) - case *ast.Ident: - // Embedded interface in this package. - embeddedIfaceType := p.auxInterfaces.Get(pkg, v.String()) - if embeddedIfaceType == nil { - embeddedIfaceType = p.importedInterfaces.Get(pkg, v.String()) - } - - var embeddedIface *model.Interface - if embeddedIfaceType != nil { +func (p *fileParser) parseMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) { + // {} for git diff + { + switch v := field.Type.(type) { + case *ast.FuncType: + if nn := len(field.Names); nn != 1 { + return nil, fmt.Errorf("expected one name for interface %v, got %d", iface.Name, nn) + } + m := &model.Method{ + Name: field.Names[0].String(), + } var err error - embeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType) + m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v, tps) if err != nil { - return err + return nil, err } - } else { - // This is built-in error interface. - if v.String() == model.ErrorInterface.Name { - embeddedIface = &model.ErrorInterface - } else { - ip, err := p.parsePackage(pkg) + return []*model.Method{m}, nil + case *ast.Ident: + // Embedded interface in this package. + embeddedIfaceType := p.auxInterfaces.Get(pkg, v.String()) + if embeddedIfaceType == nil { + embeddedIfaceType = p.importedInterfaces.Get(pkg, v.String()) + } + + var embeddedIface *model.Interface + if embeddedIfaceType != nil { + var err error + embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) + if err != nil { + return nil, err + } + embeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType) if err != nil { - return p.errorf(v.Pos(), "could not parse package %s: %v", pkg, err) + return nil, err } - if embeddedIfaceType = ip.importedInterfaces.Get(pkg, v.String()); embeddedIfaceType == nil { - return p.errorf(v.Pos(), "unknown embedded interface %s.%s", pkg, v.String()) + } else { + // This is built-in error interface. + if v.String() == model.ErrorInterface.Name { + embeddedIface = &model.ErrorInterface + } else { + ip, err := p.parsePackage(pkg) + if err != nil { + return nil, p.errorf(v.Pos(), "could not parse package %s: %v", pkg, err) + } + + if embeddedIfaceType = ip.importedInterfaces.Get(pkg, v.String()); embeddedIfaceType == nil { + return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", pkg, v.String()) + } + + embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) + if err != nil { + return nil, err + } + embeddedIface, err = ip.parseInterface(v.String(), pkg, embeddedIfaceType) + if err != nil { + return nil, err + } } + } + return embeddedIface.Methods, nil + case *ast.SelectorExpr: + // Embedded interface in another package. + filePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() + embeddedPkg, ok := p.imports[filePkg] + if !ok { + return nil, p.errorf(v.X.Pos(), "unknown package %s", filePkg) + } - embeddedIface, err = ip.parseInterface(v.String(), pkg, embeddedIfaceType) + var embeddedIface *model.Interface + var err error + embeddedIfaceType := p.auxInterfaces.Get(filePkg, sel) + if embeddedIfaceType != nil { + embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) if err != nil { - return err + return nil, err + } + embeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType) + if err != nil { + return nil, err + } + } else { + path := embeddedPkg.Path() + parser := embeddedPkg.Parser() + if parser == nil { + ip, err := p.parsePackage(path) + if err != nil { + return nil, p.errorf(v.Pos(), "could not parse package %s: %v", path, err) + } + parser = ip + p.imports[filePkg] = importedPkg{ + path: embeddedPkg.Path(), + parser: parser, + } + } + if embeddedIfaceType = parser.importedInterfaces.Get(path, sel); embeddedIfaceType == nil { + return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", path, sel) } - } - } - // Copy the methods. - for _, m := range embeddedIface.Methods { - iface.AddMethod(m) - } - case *ast.SelectorExpr: - // Embedded interface in another package. - filePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() - embeddedPkg, ok := p.imports[filePkg] - if !ok { - return p.errorf(v.X.Pos(), "unknown package %s", filePkg) - } - var embeddedIface *model.Interface - var err error - embeddedIfaceType := p.auxInterfaces.Get(filePkg, sel) - if embeddedIfaceType != nil { - embeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType) - if err != nil { - return err - } - } else { - path := embeddedPkg.Path() - parser := embeddedPkg.Parser() - if parser == nil { - ip, err := p.parsePackage(path) + embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) if err != nil { - return p.errorf(v.Pos(), "could not parse package %s: %v", path, err) + return nil, err } - parser = ip - p.imports[filePkg] = importedPkg{ - path: embeddedPkg.Path(), - parser: parser, + embeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType) + if err != nil { + return nil, err } } - if embeddedIfaceType = parser.importedInterfaces.Get(path, sel); embeddedIfaceType == nil { - return p.errorf(v.Pos(), "unknown embedded interface %s.%s", path, sel) - } - embeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType) - if err != nil { - return err - } - } - // Copy the methods. - // TODO: apply shadowing rules. - for _, m := range embeddedIface.Methods { - iface.AddMethod(m) - } - case *ast.IndexExpr: - switch vv := v.X.(type) { - case *ast.SelectorExpr: - if err := p.parseField(nil, vv, iface, pkg, tps); err != nil { - return err - } - case *ast.Ident: - if err := p.parseField(nil, vv, iface, pkg, tps); err != nil { - return err - } + // TODO: apply shadowing rules. + return embeddedIface.Methods, nil default: - return fmt.Errorf("don't know how to mock method of type %T", field.Type) + return p.parseGenericMethod(field, it, iface, pkg, tps) } - - default: - return fmt.Errorf("don't know how to mock method of type %T", field.Type) } - return nil } -func (p *fileParser) parseFunc(pkg string, f *ast.FuncType, tps map[string]bool) (inParam []*model.Parameter, variadic *model.Parameter, outParam []*model.Parameter, err error) { +func (p *fileParser) parseFunc(pkg string, f *ast.FuncType, tps map[string]model.Type) (inParam []*model.Parameter, variadic *model.Parameter, outParam []*model.Parameter, err error) { if f.Params != nil { regParams := f.Params.List if isVariadic(f) { @@ -438,7 +485,7 @@ func (p *fileParser) parseFunc(pkg string, f *ast.FuncType, tps map[string]bool) return } -func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field, tps map[string]bool) ([]*model.Parameter, error) { +func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field, tps map[string]model.Type) ([]*model.Parameter, error) { nf := 0 for _, f := range fields { nn := len(f.Names) @@ -472,7 +519,7 @@ func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field, tps map[str return ps, nil } -func (p *fileParser) parseType(pkg string, typ ast.Expr, tps map[string]bool) (model.Type, error) { +func (p *fileParser) parseType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) { switch v := typ.(type) { case *ast.ArrayType: ln := -1 @@ -514,7 +561,8 @@ func (p *fileParser) parseType(pkg string, typ ast.Expr, tps map[string]bool) (m } return &model.FuncType{In: in, Out: out, Variadic: variadic}, nil case *ast.Ident: - if v.IsExported() && !tps[v.Name] { + it, ok := tps[v.Name] + if v.IsExported() && !ok { // `pkg` may be an aliased imported pkg // if so, patch the import w/ the fully qualified import maybeImportedPkg, ok := p.imports[pkg] @@ -524,7 +572,9 @@ func (p *fileParser) parseType(pkg string, typ ast.Expr, tps map[string]bool) (m // assume type in this package return &model.NamedType{Package: pkg, Type: v.Name}, nil } - + if ok && it != nil { + return it, nil + } // assume predeclared type return model.PredeclaredType(v.Name), nil case *ast.InterfaceType: @@ -678,9 +728,11 @@ func importsOfFile(file *ast.File) (normalImports map[string]importedPackage, do } type namedInterface struct { - name *ast.Ident - it *ast.InterfaceType - typeParams []*ast.Field + name *ast.Ident + it *ast.InterfaceType + typeParams []*ast.Field + embeddedInstTypeParams []ast.Expr + instTypes []model.Type } // Create an iterator over all interfaces in file. @@ -702,7 +754,7 @@ func iterInterfaces(file *ast.File) <-chan *namedInterface { continue } - ch <- &namedInterface{ts.Name, it, getTypeSpecTypeParams(ts)} + ch <- &namedInterface{name: ts.Name, it: it, typeParams: getTypeSpecTypeParams(ts)} } } close(ch)