Skip to content

Commit

Permalink
Fix: stablize order of type params
Browse files Browse the repository at this point in the history
  • Loading branch information
petergtz committed May 9, 2023
1 parent eae31cf commit 2902b2b
Showing 1 changed file with 40 additions and 49 deletions.
89 changes: 40 additions & 49 deletions modelgen/xtools_packages/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ type Number interface {
int64 | float64
}

type Blub[K comparable, V Number] struct{}
type Blub[V Number, K comparable] struct{}

func (b *Blub[K, V]) SumNumbers(m map[K]V, i int, q string, a []float32) V {
func (b *Blub[V, K]) SumNumbers(m map[K]V, i int, _ string, a []float32, sss ...string) V {
var s V
for _, v := range m {
s += v
}
return s
}

func NewBlub[K comparable, V Number]() *Blub[K, V] {
return &Blub[K, V]{}
func NewBlub[K1 comparable, V1 Number]() Bla[K1, V1] {
return &Blub[V1, K1]{}
}

func GenerateModel(importPath string, interfaceName string) (*model.Package, error) {
Expand All @@ -44,80 +44,72 @@ func GenerateModel(importPath string, interfaceName string) (*model.Package, err
if obj == nil {
continue
}

// from here, things follow the spec in https://tip.golang.org/ref/spec
if typeName, isTypeName := obj.(*types.TypeName); isTypeName {
if iface, isIface := typeName.Type().Underlying().(*types.Interface); isIface {

g := &modelGenerator2{typeParams: make(map[string]*model.Parameter)}
methods := g.modelMethodsFrom(iface)

return &model.Package{
Name: path.Base(pkg.Types.Name()),
Interfaces: []*model.Interface{{
Name: interfaceName,
Methods: methods,
TypeParams: sliceFrom(g.typeParams),
}},
}, nil
}
if iface, isIface := obj.Type().Underlying().(*types.Interface); isIface {
return &model.Package{
Name: path.Base(pkg.Types.Name()),
Interfaces: []*model.Interface{{
Name: interfaceName,
Methods: modelMethodsFrom(iface),
TypeParams: typeParamsFrom(obj.Type().(*types.Named).TypeParams()),
}},
}, nil

}
}

return nil, errors.New("Did not find interface name \"" + interfaceName + "\"")
}

type modelGenerator2 struct {
typeParams map[string]*model.Parameter
}

func (g *modelGenerator2) modelMethodsFrom(iface *types.Interface) (modelMethods []*model.Method) {
func modelMethodsFrom(iface *types.Interface) (modelMethods []*model.Method) {
for i := 0; i < iface.NumMethods(); i++ {
modelMethods = append(modelMethods, g.modelMethodFrom(iface.Method(i)))
modelMethods = append(modelMethods, modelMethodFrom(iface.Method(i)))
}
return
}

func (g *modelGenerator2) modelMethodFrom(method *types.Func) *model.Method {
func modelMethodFrom(method *types.Func) *model.Method {
signature := method.Type().(*types.Signature)
in, variadic := g.inParamsFrom(signature)
in, variadic := inParamsFrom(signature)
return &model.Method{
Name: method.Name(),
In: in,
Variadic: variadic,
Out: g.outParamsFrom(signature),
Out: outParamsFrom(signature),
}
}

func (g *modelGenerator2) inParamsFrom(signature *types.Signature) (in []*model.Parameter, variadic *model.Parameter) {
func inParamsFrom(signature *types.Signature) (in []*model.Parameter, variadic *model.Parameter) {
for u := 0; u < signature.Params().Len(); u++ {
if signature.Variadic() && u == signature.Params().Len()-1 {
variadic = &model.Parameter{
Name: signature.Params().At(u).Name(),
Type: g.modelTypeFrom(signature.Params().At(u).Type().(*types.Slice).Elem()),
Type: modelTypeFrom(signature.Params().At(u).Type().(*types.Slice).Elem()),
}
break
}
in = append(in, &model.Parameter{
Name: signature.Params().At(u).Name(),
Type: g.modelTypeFrom(signature.Params().At(u).Type()),
Type: modelTypeFrom(signature.Params().At(u).Type()),
})
}
return
}

func (g *modelGenerator2) outParamsFrom(signature *types.Signature) (out []*model.Parameter) {
func outParamsFrom(signature *types.Signature) (out []*model.Parameter) {
if signature.Results() != nil {
for u := 0; u < signature.Results().Len(); u++ {
out = append(out, &model.Parameter{
Name: signature.Results().At(u).Name(),
Type: g.modelTypeFrom(signature.Results().At(u).Type()),
Type: modelTypeFrom(signature.Results().At(u).Type()),
})
}
}
return
}

func (g *modelGenerator2) modelTypeFrom(typesType types.Type) model.Type {
func modelTypeFrom(typesType types.Type) model.Type {
switch typedTyp := typesType.(type) {
case *types.Basic:
if !predeclared(typedTyp.Kind()) {
Expand All @@ -126,22 +118,22 @@ func (g *modelGenerator2) modelTypeFrom(typesType types.Type) model.Type {
return model.PredeclaredType(typedTyp.Name())
case *types.Pointer:
return &model.PointerType{
Type: g.modelTypeFrom(typedTyp.Elem()),
Type: modelTypeFrom(typedTyp.Elem()),
}
case *types.Array:
return &model.ArrayType{
Len: int(typedTyp.Len()),
Type: g.modelTypeFrom(typedTyp.Elem()),
Type: modelTypeFrom(typedTyp.Elem()),
}
case *types.Slice:
return &model.ArrayType{
Len: -1,
Type: g.modelTypeFrom(typedTyp.Elem()),
Type: modelTypeFrom(typedTyp.Elem()),
}
case *types.Map:
return &model.MapType{
Key: g.modelTypeFrom(typedTyp.Key()),
Value: g.modelTypeFrom(typedTyp.Elem()),
Key: modelTypeFrom(typedTyp.Key()),
Value: modelTypeFrom(typedTyp.Elem()),
}
case *types.Chan:
var dir model.ChanDir
Expand All @@ -155,7 +147,7 @@ func (g *modelGenerator2) modelTypeFrom(typesType types.Type) model.Type {
}
return &model.ChanType{
Dir: dir,
Type: g.modelTypeFrom(typedTyp.Elem()),
Type: modelTypeFrom(typedTyp.Elem()),
}
case *types.Named:
if typedTyp.Obj().Pkg() == nil {
Expand All @@ -168,22 +160,21 @@ func (g *modelGenerator2) modelTypeFrom(typesType types.Type) model.Type {
case *types.Interface, *types.Struct:
return model.PredeclaredType(typedTyp.String())
case *types.Signature:
in, variadic := g.inParamsFrom(typedTyp)
return &model.FuncType{In: in, Out: g.outParamsFrom(typedTyp), Variadic: variadic}
in, variadic := inParamsFrom(typedTyp)
return &model.FuncType{In: in, Out: outParamsFrom(typedTyp), Variadic: variadic}
case *types.TypeParam:
g.typeParams[typedTyp.Obj().Name()] = &model.Parameter{
Name: typedTyp.Obj().Name(),
Type: g.modelTypeFrom(typedTyp.Constraint()),
}
return model.PredeclaredType(typedTyp.Obj().Name())
default:
panic(fmt.Sprintf("Unknown types.Type: %v (%T)", typesType, typesType))
}
}

func sliceFrom(params map[string]*model.Parameter) (result []*model.Parameter) {
for _, v := range params {
result = append(result, v)
func typeParamsFrom(typeParams *types.TypeParamList) (result []*model.Parameter) {
for i := 0; i < typeParams.Len(); i++ {
result = append(result, &model.Parameter{
Name: typeParams.At(i).Obj().Name(),
Type: modelTypeFrom(typeParams.At(i).Constraint()),
})
}
return
}
Expand Down

0 comments on commit 2902b2b

Please sign in to comment.