1
0
mirror of https://github.com/golang/go synced 2024-11-26 07:27: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:
Robert Findley 2021-08-31 18:20:49 -04:00
parent 5cd1b847dc
commit 1a9807906d
2 changed files with 39 additions and 43 deletions

View File

@ -212,7 +212,6 @@ func (w *typeWriter) typ(typ Type) {
s = "<-chan " s = "<-chan "
default: default:
w.error("unknown channel direction") w.error("unknown channel direction")
break
} }
w.string(s) w.string(s)
if parens { if parens {

View File

@ -56,6 +56,14 @@ func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
newTypeWriter(buf, qf).typ(typ) 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. // instanceMarker is the prefix for an instantiated type in unexpanded form.
const instanceMarker = '#' 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) byte(b byte) { w.buf.WriteByte(b) }
func (w *typeWriter) string(s string) { w.buf.WriteString(s) } 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) 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) { func (w *typeWriter) typ(typ Type) {
if w.seen[typ] { if w.seen[typ] {
w.writef("○%T", goTypeName(typ)) // cycle to typ w.error("cycle to " + goTypeName(typ))
return return
} }
w.seen[typ] = true w.seen[typ] = true
@ -88,7 +102,7 @@ func (w *typeWriter) typ(typ Type) {
switch t := typ.(type) { switch t := typ.(type) {
case nil: case nil:
w.string("<nil>") w.error("nil")
case *Basic: case *Basic:
// exported basic types go into package unsafe // exported basic types go into package unsafe
@ -144,7 +158,8 @@ func (w *typeWriter) typ(typ Type) {
// Unions only appear as (syntactic) embedded elements // Unions only appear as (syntactic) embedded elements
// in interfaces and syntactically cannot be empty. // in interfaces and syntactically cannot be empty.
if t.Len() == 0 { if t.Len() == 0 {
panic("empty union") w.error("empty union")
break
} }
for i, t := range t.terms { for i, t := range t.terms {
if i > 0 { if i > 0 {
@ -197,7 +212,7 @@ func (w *typeWriter) typ(typ Type) {
case RecvOnly: case RecvOnly:
s = "<-chan " s = "<-chan "
default: default:
unreachable() w.error("unknown channel direction")
} }
w.string(s) w.string(s)
if parens { if parens {
@ -226,21 +241,21 @@ func (w *typeWriter) typ(typ Type) {
} }
case *TypeParam: case *TypeParam:
s := "?" if t.obj == nil {
if t.obj != nil { w.error("unnamed type parameter")
// Optionally write out package for typeparams (like Named). break
// TODO(danscales): this is required for import/export, so
// we maybe need a separate function that won't be changed
// for debugging purposes.
if t.obj.pkg != nil {
writePackage(w.buf, t.obj.pkg, w.qf)
}
s = t.obj.name
} }
w.string(s + subscript(t.id)) // 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
// for debugging purposes.
if t.obj.pkg != nil {
writePackage(w.buf, t.obj.pkg, w.qf)
}
w.string(t.obj.name + subscript(t.id))
case *top: case *top:
w.string("") w.error("")
default: default:
// For externally defined implementations of Type. // For externally defined implementations of Type.
@ -267,26 +282,20 @@ func (w *typeWriter) tParamList(list []*TypeParam) {
// Determine the type parameter and its constraint. // Determine the type parameter and its constraint.
// list is expected to hold type parameter names, // list is expected to hold type parameter names,
// but don't crash if that's not the case. // but don't crash if that's not the case.
var bound Type if tpar == nil {
if tpar != nil { w.error("nil type parameter")
bound = tpar.bound // should not be nil but we want to see it if it is continue
} }
if i > 0 { if i > 0 {
if bound != prev { if tpar.bound != prev {
// bound changed - write previous one before advancing // bound changed - write previous one before advancing
w.byte(' ') w.byte(' ')
w.typ(prev) w.typ(prev)
} }
w.string(", ") w.string(", ")
} }
prev = bound prev = tpar.bound
w.typ(tpar)
if tpar != nil {
w.typ(tpar)
} else {
w.string(tpar.obj.name)
}
} }
if prev != nil { if prev != nil {
w.byte(' ') w.byte(' ')
@ -296,11 +305,6 @@ func (w *typeWriter) tParamList(list []*TypeParam) {
} }
func (w *typeWriter) typeName(obj *TypeName) { 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 { if obj.pkg != nil {
writePackage(w.buf, obj.pkg, w.qf) writePackage(w.buf, obj.pkg, w.qf)
} }
@ -353,7 +357,8 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
// special case: // special case:
// append(s, "foo"...) leads to signature func([]byte, string...) // append(s, "foo"...) leads to signature func([]byte, string...)
if t := asBasic(typ); t == nil || t.kind != String { if t := asBasic(typ); t == nil || t.kind != String {
panic("expected string type") w.error("expected string type")
continue
} }
w.typ(typ) w.typ(typ)
w.string("...") w.string("...")
@ -366,14 +371,6 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
w.byte(')') 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) { func (w *typeWriter) signature(sig *Signature) {
if sig.TParams().Len() != 0 { if sig.TParams().Len() != 0 {
w.tParamList(sig.TParams().list()) w.tParamList(sig.TParams().list())