Skip to content

Commit

Permalink
support embedded generic interfaces (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
tra4less authored Jul 11, 2023
1 parent dac4550 commit 0181604
Show file tree
Hide file tree
Showing 11 changed files with 971 additions and 205 deletions.
9 changes: 4 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ module go.uber.org/mock
go 1.19

require (
golang.org/x/mod v0.5.1
golang.org/x/tools v0.1.8
golang.org/x/mod v0.11.0
golang.org/x/tools v0.2.0
)

require (
github.com/yuin/goldmark v1.4.1 // indirect
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
github.com/yuin/goldmark v1.4.13 // indirect
golang.org/x/sys v0.1.0 // indirect
)
18 changes: 8 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
github.com/yuin/goldmark v1.4.1 h1:/vn0k+RBvwlxEmP5E7SZMqNxPhfMVFEJiykr15/0XKM=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
30 changes: 29 additions & 1 deletion mockgen/generic_go118.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package main

import (
"fmt"
"go/ast"
"strings"

Expand All @@ -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)
Expand Down Expand Up @@ -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)
}
7 changes: 6 additions & 1 deletion mockgen/generic_notgo118.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package main

import (
"fmt"
"go/ast"

"go.uber.org/mock/mockgen/model"
Expand All @@ -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)
}
26 changes: 24 additions & 2 deletions mockgen/internal/tests/generics/external.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package generics

import (
"context"
"io"

"go.uber.org/mock/mockgen/internal/tests/generics/other"
"golang.org/x/exp/constraints"
)

//go:generate mockgen --source=external.go --destination=source/mock_external_test.go --package source
//go:generate mockgen --source=external.go --destination=source/mock_external_mock.go --package source

type ExternalConstraint[I constraints.Integer, F constraints.Float] interface {
type ExternalConstraint[I constraints.Integer, F any] interface {
One(string) string
Two(I) string
Three(I) F
Expand All @@ -18,4 +21,23 @@ type ExternalConstraint[I constraints.Integer, F constraints.Float] interface {
Eight(F) other.Two[I, F]
Nine(Iface[I])
Ten(*I)
Eleven() map[string]I
Twelve(ctx context.Context) <-chan []I
Thirteen(...I) *F
}

type EmbeddingIface[T constraints.Integer, R constraints.Float] interface {
io.Reader
Generator[R]
Earth[Generator[T]]
other.Either[R, StructType, other.Five, Generator[T]]
ExternalConstraint[T, R]
}

type Generator[T any] interface {
Generate() T
}

type Group[T Generator[any]] interface {
Join(ctx context.Context) []T
}
23 changes: 21 additions & 2 deletions mockgen/internal/tests/generics/generics.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package generics

import "go.uber.org/mock/mockgen/internal/tests/generics/other"
import (
"go.uber.org/mock/mockgen/internal/tests/generics/other"
"golang.org/x/exp/constraints"
)

//go:generate mockgen --source=generics.go --destination=source/mock_generics_test.go --package source
//go:generate mockgen --source=generics.go --destination=source/mock_generics_mock.go --package source
////go:generate mockgen --destination=reflect/mock_test.go --package reflect . Bar,Bar2

type Bar[T any, R any] interface {
Expand Down Expand Up @@ -38,3 +41,19 @@ type StructType struct{}
type StructType2 struct{}

type AliasType Baz[other.Three]

type Universe[T constraints.Signed] interface {
MilkyWay[T]
}

type MilkyWay[R constraints.Integer] interface {
SolarSystem[R]
}

type SolarSystem[T constraints.Ordered] interface {
Earth[T]
}

type Earth[R any] interface {
Water(R) []R
}
7 changes: 7 additions & 0 deletions mockgen/internal/tests/generics/other/other.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ type Three struct{}
type Four struct{}

type Five interface{}

type Either[T, R, K, V any] interface {
First() T
Second() R
Third() K
Fourth() V
}
Loading

0 comments on commit 0181604

Please sign in to comment.