From 2902b2b9a4444c101a16790810e7651e54d9cbe5 Mon Sep 17 00:00:00 2001 From: Peter Goetz Date: Tue, 9 May 2023 21:46:53 +0200 Subject: [PATCH] Fix: stablize order of type params --- modelgen/xtools_packages/packages.go | 89 +++++++++++++--------------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/modelgen/xtools_packages/packages.go b/modelgen/xtools_packages/packages.go index dc32554..06e3ec0 100644 --- a/modelgen/xtools_packages/packages.go +++ b/modelgen/xtools_packages/packages.go @@ -18,9 +18,9 @@ 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 @@ -28,8 +28,8 @@ func (b *Blub[K, V]) SumNumbers(m map[K]V, i int, q string, a []float32) 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) { @@ -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()) { @@ -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 @@ -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 { @@ -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 }