mirror of
https://github.com/golang/go
synced 2024-11-26 07:17:59 -07:00
go/types: more systematic error handling in typeWriter
This is a port of CL 346009 to go/types. An unnecessary break statement was removed from both the port and types2. Change-Id: I2cc1328a61100d4b01a2d26ac7bac9044440d579 Reviewed-on: https://go-review.googlesource.com/c/go/+/346558 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
5cd1b847dc
commit
1a9807906d
@ -212,7 +212,6 @@ func (w *typeWriter) typ(typ Type) {
|
||||
s = "<-chan "
|
||||
default:
|
||||
w.error("unknown channel direction")
|
||||
break
|
||||
}
|
||||
w.string(s)
|
||||
if parens {
|
||||
|
@ -56,6 +56,14 @@ func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
|
||||
newTypeWriter(buf, qf).typ(typ)
|
||||
}
|
||||
|
||||
// WriteSignature writes the representation of the signature sig to buf,
|
||||
// without a leading "func" keyword.
|
||||
// The Qualifier controls the printing of
|
||||
// package-level objects, and may be nil.
|
||||
func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
|
||||
newTypeWriter(buf, qf).signature(sig)
|
||||
}
|
||||
|
||||
// instanceMarker is the prefix for an instantiated type in unexpanded form.
|
||||
const instanceMarker = '#'
|
||||
|
||||
@ -77,10 +85,16 @@ func newTypeHasher(buf *bytes.Buffer) *typeWriter {
|
||||
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) error(msg string) {
|
||||
if w.hash {
|
||||
panic(msg)
|
||||
}
|
||||
w.string("<" + msg + ">")
|
||||
}
|
||||
|
||||
func (w *typeWriter) typ(typ Type) {
|
||||
if w.seen[typ] {
|
||||
w.writef("○%T", goTypeName(typ)) // cycle to typ
|
||||
w.error("cycle to " + goTypeName(typ))
|
||||
return
|
||||
}
|
||||
w.seen[typ] = true
|
||||
@ -88,7 +102,7 @@ func (w *typeWriter) typ(typ Type) {
|
||||
|
||||
switch t := typ.(type) {
|
||||
case nil:
|
||||
w.string("<nil>")
|
||||
w.error("nil")
|
||||
|
||||
case *Basic:
|
||||
// exported basic types go into package unsafe
|
||||
@ -144,7 +158,8 @@ func (w *typeWriter) typ(typ Type) {
|
||||
// Unions only appear as (syntactic) embedded elements
|
||||
// in interfaces and syntactically cannot be empty.
|
||||
if t.Len() == 0 {
|
||||
panic("empty union")
|
||||
w.error("empty union")
|
||||
break
|
||||
}
|
||||
for i, t := range t.terms {
|
||||
if i > 0 {
|
||||
@ -197,7 +212,7 @@ func (w *typeWriter) typ(typ Type) {
|
||||
case RecvOnly:
|
||||
s = "<-chan "
|
||||
default:
|
||||
unreachable()
|
||||
w.error("unknown channel direction")
|
||||
}
|
||||
w.string(s)
|
||||
if parens {
|
||||
@ -226,8 +241,10 @@ func (w *typeWriter) typ(typ Type) {
|
||||
}
|
||||
|
||||
case *TypeParam:
|
||||
s := "?"
|
||||
if t.obj != nil {
|
||||
if t.obj == nil {
|
||||
w.error("unnamed type parameter")
|
||||
break
|
||||
}
|
||||
// Optionally write out package for typeparams (like Named).
|
||||
// TODO(danscales): this is required for import/export, so
|
||||
// we maybe need a separate function that won't be changed
|
||||
@ -235,12 +252,10 @@ func (w *typeWriter) typ(typ Type) {
|
||||
if t.obj.pkg != nil {
|
||||
writePackage(w.buf, t.obj.pkg, w.qf)
|
||||
}
|
||||
s = t.obj.name
|
||||
}
|
||||
w.string(s + subscript(t.id))
|
||||
w.string(t.obj.name + subscript(t.id))
|
||||
|
||||
case *top:
|
||||
w.string("⊤")
|
||||
w.error("⊤")
|
||||
|
||||
default:
|
||||
// For externally defined implementations of Type.
|
||||
@ -267,26 +282,20 @@ func (w *typeWriter) tParamList(list []*TypeParam) {
|
||||
// Determine the type parameter and its constraint.
|
||||
// list is expected to hold type parameter names,
|
||||
// but don't crash if that's not the case.
|
||||
var bound Type
|
||||
if tpar != nil {
|
||||
bound = tpar.bound // should not be nil but we want to see it if it is
|
||||
if tpar == nil {
|
||||
w.error("nil type parameter")
|
||||
continue
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
if bound != prev {
|
||||
if tpar.bound != prev {
|
||||
// bound changed - write previous one before advancing
|
||||
w.byte(' ')
|
||||
w.typ(prev)
|
||||
}
|
||||
w.string(", ")
|
||||
}
|
||||
prev = bound
|
||||
|
||||
if tpar != nil {
|
||||
prev = tpar.bound
|
||||
w.typ(tpar)
|
||||
} else {
|
||||
w.string(tpar.obj.name)
|
||||
}
|
||||
}
|
||||
if prev != nil {
|
||||
w.byte(' ')
|
||||
@ -296,11 +305,6 @@ func (w *typeWriter) tParamList(list []*TypeParam) {
|
||||
}
|
||||
|
||||
func (w *typeWriter) typeName(obj *TypeName) {
|
||||
if obj == nil {
|
||||
assert(!w.hash) // we need an object for type hashing
|
||||
w.string("<Named w/o object>")
|
||||
return
|
||||
}
|
||||
if obj.pkg != nil {
|
||||
writePackage(w.buf, obj.pkg, w.qf)
|
||||
}
|
||||
@ -353,7 +357,8 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
|
||||
// special case:
|
||||
// append(s, "foo"...) leads to signature func([]byte, string...)
|
||||
if t := asBasic(typ); t == nil || t.kind != String {
|
||||
panic("expected string type")
|
||||
w.error("expected string type")
|
||||
continue
|
||||
}
|
||||
w.typ(typ)
|
||||
w.string("...")
|
||||
@ -366,14 +371,6 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
|
||||
w.byte(')')
|
||||
}
|
||||
|
||||
// WriteSignature writes the representation of the signature sig to buf,
|
||||
// without a leading "func" keyword.
|
||||
// The Qualifier controls the printing of
|
||||
// package-level objects, and may be nil.
|
||||
func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
|
||||
newTypeWriter(buf, qf).signature(sig)
|
||||
}
|
||||
|
||||
func (w *typeWriter) signature(sig *Signature) {
|
||||
if sig.TParams().Len() != 0 {
|
||||
w.tParamList(sig.TParams().list())
|
||||
|
Loading…
Reference in New Issue
Block a user