func TestNameStrategy(t *testing.T) { u := types.Universe{} // Add some types. base := u.Get(types.Name{"foo/bar", "Baz"}) base.Kind = types.Struct tmp := u.Get(types.Name{"", "[]bar.Baz"}) tmp.Kind = types.Slice tmp.Elem = base tmp = u.Get(types.Name{"", "map[string]bar.Baz"}) tmp.Kind = types.Map tmp.Key = types.String tmp.Elem = base tmp = u.Get(types.Name{"foo/other", "Baz"}) tmp.Kind = types.Struct tmp.Members = []types.Member{{ Embedded: true, Type: base, }} u.Get(types.Name{"", "string"}) o := Orderer{NewPublicNamer(0)} order := o.Order(u) orderedNames := make([]string, len(order)) for i, t := range order { orderedNames[i] = o.Name(t) } expect := []string{"Baz", "Baz", "MapStringToBaz", "SliceBaz", "String"} if e, a := expect, orderedNames; !reflect.DeepEqual(e, a) { t.Errorf("Wanted %#v, got %#v", e, a) } o = Orderer{NewRawNamer(nil)} order = o.Order(u) orderedNames = make([]string, len(order)) for i, t := range order { orderedNames[i] = o.Name(t) } expect = []string{"[]bar.Baz", "bar.Baz", "map[string]bar.Baz", "other.Baz", "string"} if e, a := expect, orderedNames; !reflect.DeepEqual(e, a) { t.Errorf("Wanted %#v, got %#v", e, a) } o = Orderer{NewPublicNamer(1)} order = o.Order(u) orderedNames = make([]string, len(order)) for i, t := range order { orderedNames[i] = o.Name(t) } expect = []string{"BarBaz", "MapStringToBarBaz", "OtherBaz", "SliceBarBaz", "String"} if e, a := expect, orderedNames; !reflect.DeepEqual(e, a) { t.Errorf("Wanted %#v, got %#v", e, a) } }
func (b *Builder) addFunc(u types.Universe, useName *types.Name, in *tc.Func) *types.Type { name := tcFuncNameToName(in.String()) if useName != nil { name = *useName } out := u.Get(name) out.Kind = types.Func out.Signature = b.convertSignature(u, in.Type().(*tc.Signature)) return out }
// walkType adds the type, and any necessary child types. func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *types.Type { // Most of the cases are underlying types of the named type. name := tcNameToName(in.String()) if useName != nil { name = *useName } switch t := in.(type) { case *tc.Struct: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Struct for i := 0; i < t.NumFields(); i++ { f := t.Field(i) m := types.Member{ Name: f.Name(), Embedded: f.Anonymous(), Tags: t.Tag(i), Type: b.walkType(u, nil, f.Type()), CommentLines: b.priorCommentLines(f.Pos()), } out.Members = append(out.Members, m) } return out case *tc.Map: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Map out.Elem = b.walkType(u, nil, t.Elem()) out.Key = b.walkType(u, nil, t.Key()) return out case *tc.Pointer: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Pointer out.Elem = b.walkType(u, nil, t.Elem()) return out case *tc.Slice: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Slice out.Elem = b.walkType(u, nil, t.Elem()) return out case *tc.Array: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Array out.Elem = b.walkType(u, nil, t.Elem()) // TODO: need to store array length, otherwise raw type name // cannot be properly written. return out case *tc.Chan: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Chan out.Elem = b.walkType(u, nil, t.Elem()) // TODO: need to store direction, otherwise raw type name // cannot be properly written. return out case *tc.Basic: out := u.Get(types.Name{ Package: "", Name: t.Name(), }) if out.Kind != types.Unknown { return out } out.Kind = types.Unsupported return out case *tc.Signature: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Func out.Signature = b.convertSignature(u, t) return out case *tc.Interface: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Interface t.Complete() for i := 0; i < t.NumMethods(); i++ { out.Methods = append(out.Methods, b.walkType(u, nil, t.Method(i).Type())) } return out case *tc.Named: switch t.Underlying().(type) { case *tc.Named, *tc.Basic: name := tcNameToName(t.String()) out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Alias out.Underlying = b.walkType(u, nil, t.Underlying()) return out default: // tc package makes everything "named" with an // underlying anonymous type--we remove that annoying // "feature" for users. This flattens those types // together. name := tcNameToName(t.String()) if out := u.Get(name); out.Kind != types.Unknown { return out // short circuit if we've already made this. } out := b.walkType(u, &name, t.Underlying()) if len(out.Methods) == 0 { // If the underlying type didn't already add // methods, add them. (Interface types will // have already added methods.) for i := 0; i < t.NumMethods(); i++ { out.Methods = append(out.Methods, b.walkType(u, nil, t.Method(i).Type())) } } return out } default: out := u.Get(name) if out.Kind != types.Unknown { return out } out.Kind = types.Unsupported fmt.Printf("Making unsupported type entry %q for: %#v\n", out, t) return out } }