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

Commit 73266f9

Browse files
authored
add support for generics for source mode (#640)
Updates: #621
1 parent d8fb947 commit 73266f9

File tree

15 files changed

+929
-81
lines changed

15 files changed

+929
-81
lines changed

.github/workflows/test.yaml

+7-1
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,16 @@ jobs:
3737
./ci/test.sh
3838
./ci/check_panic_handling.sh
3939
40-
- name: Run Go tests
40+
- name: Run Go tests all
41+
if: ${{ startsWith(matrix.go-version, '1.18') }}
4142
run: |
4243
for i in $(find $PWD -name go.mod); do
4344
pushd $(dirname $i)
4445
go test ./...
4546
popd
4647
done
48+
49+
- name: Run Go tests some
50+
if: ${{ startsWith(matrix.go-version, '1.18') == false }}
51+
run: |
52+
go test ./...

mockgen/generic_go118.go

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// See the License for the specific language governing permissions and
6+
// limitations under the License.
7+
8+
//go:build go1.18
9+
// +build go1.18
10+
11+
package main
12+
13+
import (
14+
"go/ast"
15+
"strings"
16+
17+
"github.com/golang/mock/mockgen/model"
18+
)
19+
20+
func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field {
21+
if ts == nil || ts.TypeParams == nil {
22+
return nil
23+
}
24+
return ts.TypeParams.List
25+
}
26+
27+
func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]bool) (model.Type, error) {
28+
switch v := typ.(type) {
29+
case *ast.IndexExpr:
30+
m, err := p.parseType(pkg, v.X, tps)
31+
if err != nil {
32+
return nil, err
33+
}
34+
nm, ok := m.(*model.NamedType)
35+
if !ok {
36+
return m, nil
37+
}
38+
t, err := p.parseType(pkg, v.Index, tps)
39+
if err != nil {
40+
return nil, err
41+
}
42+
nm.TypeParams = &model.TypeParametersType{TypeParameters: []model.Type{t}}
43+
return m, nil
44+
case *ast.IndexListExpr:
45+
m, err := p.parseType(pkg, v.X, tps)
46+
if err != nil {
47+
return nil, err
48+
}
49+
nm, ok := m.(*model.NamedType)
50+
if !ok {
51+
return m, nil
52+
}
53+
var ts []model.Type
54+
for _, expr := range v.Indices {
55+
t, err := p.parseType(pkg, expr, tps)
56+
if err != nil {
57+
return nil, err
58+
}
59+
ts = append(ts, t)
60+
}
61+
nm.TypeParams = &model.TypeParametersType{TypeParameters: ts}
62+
return m, nil
63+
}
64+
return nil, nil
65+
}
66+
67+
func getIdentTypeParams(decl interface{}) string {
68+
if decl == nil {
69+
return ""
70+
}
71+
ts, ok := decl.(*ast.TypeSpec)
72+
if !ok {
73+
return ""
74+
}
75+
if ts.TypeParams == nil || len(ts.TypeParams.List) == 0 {
76+
return ""
77+
}
78+
var sb strings.Builder
79+
sb.WriteString("[")
80+
for i, v := range ts.TypeParams.List {
81+
if i != 0 {
82+
sb.WriteString(", ")
83+
}
84+
sb.WriteString(v.Names[0].Name)
85+
}
86+
sb.WriteString("]")
87+
return sb.String()
88+
}

mockgen/generic_notgo118.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//go:build !go1.18
16+
// +build !go1.18
17+
18+
package main
19+
20+
import (
21+
"go/ast"
22+
23+
"github.com/golang/mock/mockgen/model"
24+
)
25+
26+
func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field {
27+
return nil
28+
}
29+
30+
func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]bool) (model.Type, error) {
31+
return nil, nil
32+
}
33+
34+
func getIdentTypeParams(decl interface{}) string {
35+
return ""
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package generics
2+
3+
import (
4+
"github.com/golang/mock/mockgen/internal/tests/generics/other"
5+
"golang.org/x/exp/constraints"
6+
)
7+
8+
//go:generate mockgen --source=external.go --destination=source/mock_external_test.go --package source
9+
10+
type ExternalConstraint[I constraints.Integer, F constraints.Float] interface {
11+
One(string) string
12+
Two(I) string
13+
Three(I) F
14+
Four(I) Foo[I, F]
15+
Five(I) Baz[F]
16+
Six(I) *Baz[F]
17+
Seven(I) other.One[I]
18+
Eight(F) other.Two[I, F]
19+
Nine(Iface[I])
20+
Ten(*I)
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package generics
2+
3+
import "github.com/golang/mock/mockgen/internal/tests/generics/other"
4+
5+
//go:generate mockgen --source=generics.go --destination=source/mock_generics_test.go --package source
6+
////go:generate mockgen --destination=reflect/mock_test.go --package reflect . Bar,Bar2
7+
8+
type Bar[T any, R any] interface {
9+
One(string) string
10+
Two(T) string
11+
Three(T) R
12+
Four(T) Foo[T, R]
13+
Five(T) Baz[T]
14+
Six(T) *Baz[T]
15+
Seven(T) other.One[T]
16+
Eight(T) other.Two[T, R]
17+
Nine(Iface[T])
18+
Ten(*T)
19+
Eleven() (*other.One[T], error)
20+
Twelve() (*other.Two[T, R], error)
21+
Thirteen() (Baz[StructType], error)
22+
Fourteen() (*Foo[StructType, StructType2], error)
23+
Fifteen() (Iface[StructType], error)
24+
Sixteen() (Baz[other.Three], error)
25+
Seventeen() (*Foo[other.Three, other.Four], error)
26+
Eighteen() (Iface[*other.Five], error)
27+
Nineteen() AliasType
28+
}
29+
30+
type Foo[T any, R any] struct{}
31+
32+
type Baz[T any] struct{}
33+
34+
type Iface[T any] interface{}
35+
36+
type StructType struct{}
37+
38+
type StructType2 struct{}
39+
40+
type AliasType Baz[other.Three]
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/golang/mock/mockgen/internal/tests/generics
2+
3+
go 1.18
4+
5+
require (
6+
github.com/golang/mock v1.6.0
7+
golang.org/x/exp v0.0.0-20220428152302-39d4317da171
8+
)
9+
10+
replace github.com/golang/mock => ../../../..
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
2+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
3+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
4+
golang.org/x/exp v0.0.0-20220428152302-39d4317da171 h1:TfdoLivD44QwvssI9Sv1xwa5DcL5XQr4au4sZ2F2NV4=
5+
golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
6+
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
7+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
8+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
9+
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
10+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
11+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
12+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
13+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
14+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
15+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
16+
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
17+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
18+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
19+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
20+
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
21+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
22+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
23+
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
24+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
25+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
26+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package other
2+
3+
type One[T any] struct{}
4+
5+
type Two[T any, R any] struct{}
6+
7+
type Three struct{}
8+
9+
type Four struct{}
10+
11+
type Five interface{}

0 commit comments

Comments
 (0)