]> Cypherpunks repositories - gostls13.git/commitdiff
exp/types: Replace String method with TypeString function
authorRobert Griesemer <gri@golang.org>
Wed, 1 Aug 2012 02:30:18 +0000 (19:30 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 1 Aug 2012 02:30:18 +0000 (19:30 -0700)
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

src/pkg/exp/types/types.go
src/pkg/exp/types/types_test.go

index 0e844107cba7ac06728b11917caf5872e7bfc5bb..50d85b76443593b6ac80654dac4629ab85656600 100644 (file)
@@ -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;
index b2c22d747a960239ab8a822873d63629a7b7d1cf..c49f366a863d7a99f9ac4561587cfdc9b7f93f60 100644 (file)
@@ -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)
                }