Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 0181604

Browse files
authored
support embedded generic interfaces (#13)
migrate #669 fixes #668 #658 #700
1 parent dac4550 commit 0181604

File tree

11 files changed

+971
-205
lines changed

11 files changed

+971
-205
lines changed

go.mod

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ module go.uber.org/mock
33
go 1.19
44

55
require (
6-
golang.org/x/mod v0.5.1
7-
golang.org/x/tools v0.1.8
6+
golang.org/x/mod v0.11.0
7+
golang.org/x/tools v0.2.0
88
)
99

1010
require (
11-
github.com/yuin/goldmark v1.4.1 // indirect
12-
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
13-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
11+
github.com/yuin/goldmark v1.4.13 // indirect
12+
golang.org/x/sys v0.1.0 // indirect
1413
)

go.sum

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
github.com/yuin/goldmark v1.4.1 h1:/vn0k+RBvwlxEmP5E7SZMqNxPhfMVFEJiykr15/0XKM=
2-
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
3-
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
4-
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
5-
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
6-
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
7-
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
8-
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
9-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
10-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
1+
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
2+
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
3+
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
4+
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
5+
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
6+
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
7+
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
8+
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=

mockgen/generic_go118.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package main
1212

1313
import (
14+
"fmt"
1415
"go/ast"
1516
"strings"
1617

@@ -24,7 +25,7 @@ func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field {
2425
return ts.TypeParams.List
2526
}
2627

27-
func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]bool) (model.Type, error) {
28+
func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) {
2829
switch v := typ.(type) {
2930
case *ast.IndexExpr:
3031
m, err := p.parseType(pkg, v.X, tps)
@@ -86,3 +87,30 @@ func getIdentTypeParams(decl interface{}) string {
8687
sb.WriteString("]")
8788
return sb.String()
8889
}
90+
91+
func (p *fileParser) parseGenericMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) {
92+
var indices []ast.Expr
93+
var typ ast.Expr
94+
switch v := field.Type.(type) {
95+
case *ast.IndexExpr:
96+
indices = []ast.Expr{v.Index}
97+
typ = v.X
98+
case *ast.IndexListExpr:
99+
indices = v.Indices
100+
typ = v.X
101+
default:
102+
return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type)
103+
}
104+
105+
nf := &ast.Field{
106+
Doc: field.Comment,
107+
Names: field.Names,
108+
Type: typ,
109+
Tag: field.Tag,
110+
Comment: field.Comment,
111+
}
112+
113+
it.embeddedInstTypeParams = indices
114+
115+
return p.parseMethod(nf, it, iface, pkg, tps)
116+
}

mockgen/generic_notgo118.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package main
1919

2020
import (
21+
"fmt"
2122
"go/ast"
2223

2324
"go.uber.org/mock/mockgen/model"
@@ -27,10 +28,14 @@ func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field {
2728
return nil
2829
}
2930

30-
func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]bool) (model.Type, error) {
31+
func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) {
3132
return nil, nil
3233
}
3334

3435
func getIdentTypeParams(decl interface{}) string {
3536
return ""
3637
}
38+
39+
func (p *fileParser) parseGenericMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) {
40+
return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type)
41+
}

mockgen/internal/tests/generics/external.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package generics
22

33
import (
4+
"context"
5+
"io"
6+
47
"go.uber.org/mock/mockgen/internal/tests/generics/other"
58
"golang.org/x/exp/constraints"
69
)
710

8-
//go:generate mockgen --source=external.go --destination=source/mock_external_test.go --package source
11+
//go:generate mockgen --source=external.go --destination=source/mock_external_mock.go --package source
912

10-
type ExternalConstraint[I constraints.Integer, F constraints.Float] interface {
13+
type ExternalConstraint[I constraints.Integer, F any] interface {
1114
One(string) string
1215
Two(I) string
1316
Three(I) F
@@ -18,4 +21,23 @@ type ExternalConstraint[I constraints.Integer, F constraints.Float] interface {
1821
Eight(F) other.Two[I, F]
1922
Nine(Iface[I])
2023
Ten(*I)
24+
Eleven() map[string]I
25+
Twelve(ctx context.Context) <-chan []I
26+
Thirteen(...I) *F
27+
}
28+
29+
type EmbeddingIface[T constraints.Integer, R constraints.Float] interface {
30+
io.Reader
31+
Generator[R]
32+
Earth[Generator[T]]
33+
other.Either[R, StructType, other.Five, Generator[T]]
34+
ExternalConstraint[T, R]
35+
}
36+
37+
type Generator[T any] interface {
38+
Generate() T
39+
}
40+
41+
type Group[T Generator[any]] interface {
42+
Join(ctx context.Context) []T
2143
}

mockgen/internal/tests/generics/generics.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package generics
22

3-
import "go.uber.org/mock/mockgen/internal/tests/generics/other"
3+
import (
4+
"go.uber.org/mock/mockgen/internal/tests/generics/other"
5+
"golang.org/x/exp/constraints"
6+
)
47

5-
//go:generate mockgen --source=generics.go --destination=source/mock_generics_test.go --package source
8+
//go:generate mockgen --source=generics.go --destination=source/mock_generics_mock.go --package source
69
////go:generate mockgen --destination=reflect/mock_test.go --package reflect . Bar,Bar2
710

811
type Bar[T any, R any] interface {
@@ -38,3 +41,19 @@ type StructType struct{}
3841
type StructType2 struct{}
3942

4043
type AliasType Baz[other.Three]
44+
45+
type Universe[T constraints.Signed] interface {
46+
MilkyWay[T]
47+
}
48+
49+
type MilkyWay[R constraints.Integer] interface {
50+
SolarSystem[R]
51+
}
52+
53+
type SolarSystem[T constraints.Ordered] interface {
54+
Earth[T]
55+
}
56+
57+
type Earth[R any] interface {
58+
Water(R) []R
59+
}

mockgen/internal/tests/generics/other/other.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ type Three struct{}
99
type Four struct{}
1010

1111
type Five interface{}
12+
13+
type Either[T, R, K, V any] interface {
14+
First() T
15+
Second() R
16+
Third() K
17+
Fourth() V
18+
}

0 commit comments

Comments
 (0)