aboutsummaryrefslogtreecommitdiff
path: root/src/go/types/typestring.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/go/types/typestring.go')
-rw-r--r--src/go/types/typestring.go110
1 files changed, 67 insertions, 43 deletions
diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go
index fe27f0f276..c0c69624ec 100644
--- a/src/go/types/typestring.go
+++ b/src/go/types/typestring.go
@@ -158,12 +158,19 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
buf.WriteString("func")
writeSignature(buf, t, qf, visited)
- case *_Sum:
- for i, t := range t.types {
+ case *Union:
+ if t.IsEmpty() {
+ buf.WriteString("⊥")
+ break
+ }
+ for i, t := range t.terms {
if i > 0 {
- buf.WriteString(", ")
+ buf.WriteByte('|')
}
- writeType(buf, t, qf, visited)
+ if t.tilde {
+ buf.WriteByte('~')
+ }
+ writeType(buf, t.typ, qf, visited)
}
case *Interface:
@@ -183,7 +190,8 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
if gcCompatibilityMode {
// print flattened interface
// (useful to compare against gc-generated interfaces)
- for i, m := range t.allMethods {
+ tset := t.typeSet()
+ for i, m := range tset.methods {
if i > 0 {
buf.WriteString("; ")
}
@@ -191,12 +199,12 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
writeSignature(buf, m.typ.(*Signature), qf, visited)
empty = false
}
- if !empty && t.allTypes != nil {
+ if !empty && tset.types != nil {
buf.WriteString("; ")
}
- if t.allTypes != nil {
+ if tset.types != nil {
buf.WriteString("type ")
- writeType(buf, t.allTypes, qf, visited)
+ writeType(buf, tset.types, qf, visited)
}
} else {
// print explicit interface methods and embedded types
@@ -208,14 +216,6 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
writeSignature(buf, m.typ.(*Signature), qf, visited)
empty = false
}
- if !empty && t.types != nil {
- buf.WriteString("; ")
- }
- if t.types != nil {
- buf.WriteString("type ")
- writeType(buf, t.types, qf, visited)
- empty = false
- }
if !empty && len(t.embeddeds) > 0 {
buf.WriteString("; ")
}
@@ -227,7 +227,9 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
empty = false
}
}
- if t.allMethods == nil || len(t.methods) > len(t.allMethods) {
+ // print /* incomplete */ if needed to satisfy existing tests
+ // TODO(gri) get rid of this eventually
+ if debug && t.tset == nil {
if !empty {
buf.WriteByte(' ')
}
@@ -268,39 +270,40 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
}
case *Named:
+ if t.instance != nil {
+ buf.WriteByte(instanceMarker)
+ }
writeTypeName(buf, t.obj, qf)
if t.targs != nil {
// instantiated type
buf.WriteByte('[')
writeTypeList(buf, t.targs, qf, visited)
buf.WriteByte(']')
- } else if t.tparams != nil {
+ } else if t.TParams().Len() != 0 {
// parameterized type
- writeTParamList(buf, t.tparams, qf, visited)
+ writeTParamList(buf, t.TParams().list(), qf, visited)
}
- case *_TypeParam:
+ case *TypeParam:
s := "?"
if t.obj != nil {
+ // Optionally write out package for typeparams (like Named).
+ // TODO(rfindley): 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(buf, t.obj.pkg, qf)
+ }
s = t.obj.name
}
buf.WriteString(s + subscript(t.id))
- case *instance:
- buf.WriteByte(instanceMarker) // indicate "non-evaluated" syntactic instance
- writeTypeName(buf, t.base.obj, qf)
- buf.WriteByte('[')
- writeTypeList(buf, t.targs, qf, visited)
- buf.WriteByte(']')
-
- case *bottom:
- buf.WriteString("⊥")
-
case *top:
buf.WriteString("⊤")
default:
// For externally defined implementations of Type.
+ // Note: In this case cycles won't be caught.
buf.WriteString(t.String())
}
}
@@ -321,7 +324,7 @@ func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited
for i, p := range list {
// TODO(rFindley) support 'any' sugar here.
var b Type = &emptyInterface
- if t, _ := p.typ.(*_TypeParam); t != nil && t.bound != nil {
+ if t, _ := p.typ.(*TypeParam); t != nil && t.bound != nil {
b = t.bound
}
if i > 0 {
@@ -334,7 +337,7 @@ func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited
}
prev = b
- if t, _ := p.typ.(*_TypeParam); t != nil {
+ if t, _ := p.typ.(*TypeParam); t != nil {
writeType(buf, t, qf, visited)
} else {
buf.WriteString(p.name)
@@ -348,17 +351,38 @@ func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited
}
func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
- s := "<Named w/o object>"
- if obj != nil {
- if obj.pkg != nil {
- writePackage(buf, obj.pkg, qf)
+ if obj == nil {
+ buf.WriteString("<Named w/o object>")
+ return
+ }
+ if obj.pkg != nil {
+ writePackage(buf, obj.pkg, qf)
+ }
+ buf.WriteString(obj.name)
+
+ if instanceHashing != 0 {
+ // For local defined types, use the (original!) TypeName's scope
+ // numbers to disambiguate.
+ typ := obj.typ.(*Named)
+ // TODO(gri) Figure out why typ.orig != typ.orig.orig sometimes
+ // and whether the loop can iterate more than twice.
+ // (It seems somehow connected to instance types.)
+ for typ.orig != typ {
+ typ = typ.orig
}
- // TODO(gri): function-local named types should be displayed
- // differently from named types at package level to avoid
- // ambiguity.
- s = obj.name
+ writeScopeNumbers(buf, typ.obj.parent)
+ }
+}
+
+// writeScopeNumbers writes the number sequence for this scope to buf
+// in the form ".i.j.k" where i, j, k, etc. stand for scope numbers.
+// If a scope is nil or has no parent (such as a package scope), nothing
+// is written.
+func writeScopeNumbers(buf *bytes.Buffer, s *Scope) {
+ if s != nil && s.number > 0 {
+ writeScopeNumbers(buf, s.parent)
+ fmt.Fprintf(buf, ".%d", s.number)
}
- buf.WriteString(s)
}
func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {
@@ -403,8 +427,8 @@ func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
}
func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []Type) {
- if sig.tparams != nil {
- writeTParamList(buf, sig.tparams, qf, visited)
+ if sig.TParams().Len() != 0 {
+ writeTParamList(buf, sig.TParams().list(), qf, visited)
}
writeTuple(buf, sig.params, sig.variadic, qf, visited)