From: Robert Griesemer Date: Wed, 1 Aug 2012 02:30:18 +0000 (-0700) Subject: exp/types: Replace String method with TypeString function X-Git-Tag: go1.1rc2~2728 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=152279f203e75f923c510e4cabae6405046ba7f6;p=gostls13.git exp/types: Replace String method with TypeString function This is more in sync with the rest of the package; for instance, we have functions (not methods) to deref or find the underlying type of a Type. In the process use a single bytes.Buffer to create the string representation for a type rather than the (occasional) string concatenation. R=r CC=golang-dev https://golang.org/cl/6458057 --- diff --git a/src/pkg/exp/types/types.go b/src/pkg/exp/types/types.go index 0e844107cb..50d85b7644 100644 --- a/src/pkg/exp/types/types.go +++ b/src/pkg/exp/types/types.go @@ -17,7 +17,6 @@ import ( // All types implement the Type interface. type Type interface { isType() - String() string } // All concrete types embed implementsType which @@ -32,21 +31,12 @@ type Bad struct { Msg string // for better error reporting/debugging } -func (t *Bad) String() string { - return fmt.Sprintf("badType(%s)", t.Msg) -} - // A Basic represents a (unnamed) basic type. type Basic struct { implementsType // TODO(gri) need a field specifying the exact basic type } -func (t *Basic) String() string { - // TODO(gri) print actual type information - return "basicType" -} - // An Array represents an array type [Len]Elt. type Array struct { implementsType @@ -54,20 +44,12 @@ type Array struct { Elt Type } -func (t *Array) String() string { - return fmt.Sprintf("[%d]%s", t.Len, t.Elt) -} - // A Slice represents a slice type []Elt. type Slice struct { implementsType Elt Type } -func (t *Slice) String() string { - return "[]" + t.Elt.String() -} - // A Struct represents a struct type struct{...}. // Anonymous fields are represented by objects with empty names. type Struct struct { @@ -80,35 +62,12 @@ type Struct struct { // - there is no scope for fast lookup (but the parser creates one) } -func (t *Struct) String() string { - buf := bytes.NewBufferString("struct{") - for i, fld := range t.Fields { - if i > 0 { - buf.WriteString("; ") - } - if fld.Name != "" { - buf.WriteString(fld.Name) - buf.WriteByte(' ') - } - buf.WriteString(fld.Type.(Type).String()) - if i < len(t.Tags) && t.Tags[i] != "" { - fmt.Fprintf(buf, " %q", t.Tags[i]) - } - } - buf.WriteByte('}') - return buf.String() -} - // A Pointer represents a pointer type *Base. type Pointer struct { implementsType Base Type } -func (t *Pointer) String() string { - return "*" + t.Base.String() -} - // A Func represents a function type func(...) (...). // Unnamed parameters are represented by objects with empty names. type Func struct { @@ -119,6 +78,33 @@ type Func struct { IsVariadic bool // true if the last parameter's type is of the form ...T } +// An Interface represents an interface type interface{...}. +type Interface struct { + implementsType + Methods ObjList // interface methods sorted by name; or nil +} + +// A Map represents a map type map[Key]Elt. +type Map struct { + implementsType + Key, Elt Type +} + +// A Chan represents a channel type chan Elt, <-chan Elt, or chan<-Elt. +type Chan struct { + implementsType + Dir ast.ChanDir + Elt Type +} + +// A Name represents a named type as declared in a type declaration. +type Name struct { + implementsType + Underlying Type // nil if not fully declared + Obj *ast.Object // corresponding declared object + // TODO(gri) need to remember fields and methods. +} + func writeParams(buf *bytes.Buffer, params ObjList, isVariadic bool) { buf.WriteByte('(') for i, par := range params { @@ -132,7 +118,7 @@ func writeParams(buf *bytes.Buffer, params ObjList, isVariadic bool) { if isVariadic && i == len(params)-1 { buf.WriteString("...") } - buf.WriteString(par.Type.(Type).String()) + writeType(buf, par.Type.(Type)) } buf.WriteByte(')') } @@ -147,7 +133,7 @@ func writeSignature(buf *bytes.Buffer, t *Func) { buf.WriteByte(' ') if len(t.Results) == 1 && t.Results[0].Name == "" { // single unnamed result - buf.WriteString(t.Results[0].Type.(Type).String()) + writeType(buf, t.Results[0].Type.(Type)) return } @@ -155,71 +141,88 @@ func writeSignature(buf *bytes.Buffer, t *Func) { writeParams(buf, t.Results, false) } -func (t *Func) String() string { - buf := bytes.NewBufferString("func") - writeSignature(buf, t) - return buf.String() -} +func writeType(buf *bytes.Buffer, typ Type) { + switch t := typ.(type) { + case *Bad: + fmt.Fprintf(buf, "badType(%s)", t.Msg) -// An Interface represents an interface type interface{...}. -type Interface struct { - implementsType - Methods ObjList // interface methods sorted by name; or nil -} + case *Basic: + buf.WriteString("basicType") // TODO(gri) print actual type information -func (t *Interface) String() string { - buf := bytes.NewBufferString("interface{") - for i, m := range t.Methods { - if i > 0 { - buf.WriteString("; ") + case *Array: + fmt.Fprintf(buf, "[%d]", t.Len) + writeType(buf, t.Elt) + + case *Slice: + buf.WriteString("[]") + writeType(buf, t.Elt) + + case *Struct: + buf.WriteString("struct{") + for i, fld := range t.Fields { + if i > 0 { + buf.WriteString("; ") + } + if fld.Name != "" { + buf.WriteString(fld.Name) + buf.WriteByte(' ') + } + writeType(buf, fld.Type.(Type)) + if i < len(t.Tags) && t.Tags[i] != "" { + fmt.Fprintf(buf, " %q", t.Tags[i]) + } } - buf.WriteString(m.Name) - writeSignature(buf, m.Type.(*Func)) - } - buf.WriteByte('}') - return buf.String() -} + buf.WriteByte('}') -// A Map represents a map type map[Key]Elt. -type Map struct { - implementsType - Key, Elt Type -} + case *Pointer: + buf.WriteByte('*') + writeType(buf, t.Base) -func (t *Map) String() string { - return fmt.Sprintf("map[%s]%s", t.Key, t.Elt) -} + case *Func: + buf.WriteString("func") + writeSignature(buf, t) -// A Chan represents a channel type chan Elt, <-chan Elt, or chan<-Elt. -type Chan struct { - implementsType - Dir ast.ChanDir - Elt Type -} + case *Interface: + buf.WriteString("interface{") + for i, m := range t.Methods { + if i > 0 { + buf.WriteString("; ") + } + buf.WriteString(m.Name) + writeSignature(buf, m.Type.(*Func)) + } + buf.WriteByte('}') -func (t *Chan) String() string { - var s string - switch t.Dir { - case ast.SEND: - s = "chan<- " - case ast.RECV: - s = "<-chan " - default: - s = "chan " - } - return s + t.Elt.String() -} + case *Map: + buf.WriteString("map[") + writeType(buf, t.Key) + buf.WriteByte(']') + writeType(buf, t.Elt) -// A Name represents a named type as declared in a type declaration. -type Name struct { - implementsType - Underlying Type // nil if not fully declared - Obj *ast.Object // corresponding declared object - // TODO(gri) need to remember fields and methods. + case *Chan: + var s string + switch t.Dir { + case ast.SEND: + s = "chan<- " + case ast.RECV: + s = "<-chan " + default: + s = "chan " + } + buf.WriteString(s) + writeType(buf, t.Elt) + + case *Name: + buf.WriteString(t.Obj.Name) + + } } -func (t *Name) String() string { - return t.Obj.Name +// TypeString returns a string representation for typ. +func TypeString(typ Type) string { + var buf bytes.Buffer + writeType(&buf, typ) + return buf.String() } // If typ is a pointer type, Deref returns the pointer's base type; diff --git a/src/pkg/exp/types/types_test.go b/src/pkg/exp/types/types_test.go index b2c22d747a..c49f366a86 100644 --- a/src/pkg/exp/types/types_test.go +++ b/src/pkg/exp/types/types_test.go @@ -120,7 +120,7 @@ func TestTypes(t *testing.T) { continue } typ := Underlying(pkg.Scope.Lookup("T").Type.(Type)) - str := typ.String() + str := TypeString(typ) if str != test.str { t.Errorf("%s: got %s, want %s", test.src, str, test.str) }