mirror of https://github.com/golang/go.git
go/types: return typeHash value without blanks
This is an adjusted port of CL 349990 from types2 to go/types: typeHash remains unexported but is adjusted to not contain blanks. Change-Id: I37fa826b8a185e3c275ae9bea29a3b0ed386d2c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/351171 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
7dfe686a91
commit
ebc6ce40ce
|
|
@ -6,6 +6,7 @@ package types
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ func NewEnvironment() *Environment {
|
|||
// typeHash returns a string representation of typ, which can be used as an exact
|
||||
// type hash: types that are identical produce identical string representations.
|
||||
// If typ is a *Named type and targs is not empty, typ is printed as if it were
|
||||
// instantiated with targs.
|
||||
// instantiated with targs. The result is guaranteed to not contain blanks (" ").
|
||||
func (env *Environment) typeHash(typ Type, targs []Type) string {
|
||||
assert(env != nil)
|
||||
assert(typ != nil)
|
||||
|
|
@ -50,7 +51,7 @@ func (env *Environment) typeHash(typ Type, targs []Type) string {
|
|||
h.typ(typ)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
return strings.Replace(buf.String(), " ", "#", -1) // ReplaceAll is not available in Go1.4
|
||||
}
|
||||
|
||||
// typeForHash returns the recorded type for the type hash h, if it exists.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ package types
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/token"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
|
|
@ -81,14 +80,29 @@ func newTypeHasher(buf *bytes.Buffer, env *Environment) *typeWriter {
|
|||
return &typeWriter{buf, make(map[Type]bool), nil, env}
|
||||
}
|
||||
|
||||
func (w *typeWriter) byte(b byte) { w.buf.WriteByte(b) }
|
||||
func (w *typeWriter) string(s string) { w.buf.WriteString(s) }
|
||||
func (w *typeWriter) writef(format string, args ...interface{}) { fmt.Fprintf(w.buf, format, args...) }
|
||||
func (w *typeWriter) byte(b byte) {
|
||||
if w.env != nil {
|
||||
if b == ' ' {
|
||||
b = '#'
|
||||
}
|
||||
w.buf.WriteByte(b)
|
||||
return
|
||||
}
|
||||
w.buf.WriteByte(b)
|
||||
if b == ',' || b == ';' {
|
||||
w.buf.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
|
||||
func (w *typeWriter) string(s string) {
|
||||
w.buf.WriteString(s)
|
||||
}
|
||||
|
||||
func (w *typeWriter) error(msg string) {
|
||||
if w.env != nil {
|
||||
panic(msg)
|
||||
}
|
||||
w.string("<" + msg + ">")
|
||||
w.buf.WriteString("<" + msg + ">")
|
||||
}
|
||||
|
||||
func (w *typeWriter) typ(typ Type) {
|
||||
|
|
@ -115,7 +129,9 @@ func (w *typeWriter) typ(typ Type) {
|
|||
w.string(t.name)
|
||||
|
||||
case *Array:
|
||||
w.writef("[%d]", t.len)
|
||||
w.byte('[')
|
||||
w.string(strconv.FormatInt(t.len, 10))
|
||||
w.byte(']')
|
||||
w.typ(t.elem)
|
||||
|
||||
case *Slice:
|
||||
|
|
@ -126,7 +142,7 @@ func (w *typeWriter) typ(typ Type) {
|
|||
w.string("struct{")
|
||||
for i, f := range t.fields {
|
||||
if i > 0 {
|
||||
w.string("; ")
|
||||
w.byte(';')
|
||||
}
|
||||
// This doesn't do the right thing for embedded type
|
||||
// aliases where we should print the alias name, not
|
||||
|
|
@ -137,7 +153,11 @@ func (w *typeWriter) typ(typ Type) {
|
|||
}
|
||||
w.typ(f.typ)
|
||||
if tag := t.Tag(i); tag != "" {
|
||||
w.writef(" %q", tag)
|
||||
w.byte(' ')
|
||||
// TODO(rfindley) If tag contains blanks, replacing them with '#'
|
||||
// in Environment.TypeHash may produce another tag
|
||||
// accidentally.
|
||||
w.string(strconv.Quote(tag))
|
||||
}
|
||||
}
|
||||
w.byte('}')
|
||||
|
|
@ -175,7 +195,7 @@ func (w *typeWriter) typ(typ Type) {
|
|||
first := true
|
||||
for _, m := range t.methods {
|
||||
if !first {
|
||||
w.string("; ")
|
||||
w.byte(';')
|
||||
}
|
||||
first = false
|
||||
w.string(m.name)
|
||||
|
|
@ -183,7 +203,7 @@ func (w *typeWriter) typ(typ Type) {
|
|||
}
|
||||
for _, typ := range t.embeddeds {
|
||||
if !first {
|
||||
w.string("; ")
|
||||
w.byte(';')
|
||||
}
|
||||
first = false
|
||||
w.typ(typ)
|
||||
|
|
@ -270,7 +290,7 @@ func (w *typeWriter) typeList(list []Type) {
|
|||
w.byte('[')
|
||||
for i, typ := range list {
|
||||
if i > 0 {
|
||||
w.string(", ")
|
||||
w.byte(',')
|
||||
}
|
||||
w.typ(typ)
|
||||
}
|
||||
|
|
@ -294,7 +314,7 @@ func (w *typeWriter) tParamList(list []*TypeParam) {
|
|||
w.byte(' ')
|
||||
w.typ(prev)
|
||||
}
|
||||
w.string(", ")
|
||||
w.byte(',')
|
||||
}
|
||||
prev = tpar.bound
|
||||
w.typ(tpar)
|
||||
|
|
@ -318,7 +338,7 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
|
|||
if tup != nil {
|
||||
for i, v := range tup.vars {
|
||||
if i > 0 {
|
||||
w.string(", ")
|
||||
w.byte(',')
|
||||
}
|
||||
// parameter names are ignored for type identity and thus type hashes
|
||||
if w.env == nil && v.name != "" {
|
||||
|
|
|
|||
Loading…
Reference in New Issue