1
0
mirror of https://github.com/golang/go synced 2024-11-22 21:10:03 -07:00

the first time a structure type appears when printing, identify it by name:

type Foo struct { a int; next *Foo }
produces
	"Foo = struct { a int; next Foo }"

R=rsc
OCL=30797
CL=30820
This commit is contained in:
Rob Pike 2009-06-26 20:28:06 -07:00
parent d6197d94b5
commit ac7f2152eb
2 changed files with 15 additions and 5 deletions

View File

@ -8,7 +8,9 @@ import (
"fmt"; "fmt";
"os"; "os";
"reflect"; "reflect";
"strings";
"sync"; "sync";
"unicode";
) )
var id uint32 // incremented for each new type we build var id uint32 // incremented for each new type we build
@ -119,7 +121,7 @@ func (s *structType) safeString(seen map[uint32] bool) string {
return s.name return s.name
} }
seen[s._id] = true; seen[s._id] = true;
str := "struct { "; str := s.name + " = struct { ";
for _, f := range s.field { for _, f := range s.field {
str += fmt.Sprintf("%s %s; ", f.name, f.typ.safeString(seen)); str += fmt.Sprintf("%s %s; ", f.name, f.typ.safeString(seen));
} }
@ -170,8 +172,15 @@ func newTypeObject(name string, rt reflect.Type) Type {
st := rt.(reflect.StructType); st := rt.(reflect.StructType);
field := make([]*fieldType, st.Len()); field := make([]*fieldType, st.Len());
for i := 0; i < st.Len(); i++ { for i := 0; i < st.Len(); i++ {
name, typ, tag, offset := st.Field(i); name, typ, _tag, _offset := st.Field(i);
field[i] = &fieldType{ name, newType("", typ) }; // Find trailing name in type, e.g. from "*gob.Bar" want "Bar", which
// is defined as the word after the period (there is at most one period).
typestring := typ.String();
period := strings.Index(typestring, ".");
if period >= 0 {
typestring = typestring[period+1:len(typestring)]
}
field[i] = &fieldType{ name, newType(typestring, typ) };
} }
strType.field = field; strType.field = field;
return strType; return strType;

View File

@ -118,14 +118,15 @@ type Foo struct {
d *float; // will become float32 d *float; // will become float32
e ****float64; // will become float64 e ****float64; // will become float64
f *Bar; f *Bar;
g *Foo; // will not explode g *Bar; // should not interpolate the definition of Bar again
h *Foo; // will not explode
} }
func TestStructType(t *testing.T) { func TestStructType(t *testing.T) {
sstruct := GetType("Foo", Foo{}); sstruct := GetType("Foo", Foo{});
str := sstruct.String(); str := sstruct.String();
// If we can print it correctly, we built it correctly. // If we can print it correctly, we built it correctly.
expected := "struct { a int; b int; c string; d float32; e float64; f struct { x string; }; g Foo; }"; expected := "Foo = struct { a int; b int; c string; d float32; e float64; f Bar = struct { x string; }; g Bar; h Foo; }";
if str != expected { if str != expected {
t.Errorf("struct printed as %q; expected %q", str, expected); t.Errorf("struct printed as %q; expected %q", str, expected);
} }