mirror of
https://github.com/golang/go
synced 2024-11-26 09:48:14 -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 "
|
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 {
|
||||||
|
@ -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,8 +241,10 @@ func (w *typeWriter) typ(typ Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case *TypeParam:
|
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).
|
// Optionally write out package for typeparams (like Named).
|
||||||
// TODO(danscales): this is required for import/export, so
|
// TODO(danscales): this is required for import/export, so
|
||||||
// we maybe need a separate function that won't be changed
|
// 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 {
|
if t.obj.pkg != nil {
|
||||||
writePackage(w.buf, t.obj.pkg, w.qf)
|
writePackage(w.buf, t.obj.pkg, w.qf)
|
||||||
}
|
}
|
||||||
s = t.obj.name
|
w.string(t.obj.name + subscript(t.id))
|
||||||
}
|
|
||||||
w.string(s + 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
|
||||||
|
|
||||||
if tpar != nil {
|
|
||||||
w.typ(tpar)
|
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())
|
||||||
|
Loading…
Reference in New Issue
Block a user