1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // This file implements writing of types. The functionality is lifted
6 // directly from go/types, but now contains various modifications for
9 // TODO(gri) back-port once we have a fixed interface and once the
10 // go/types API is not frozen anymore for the 1.3 release; and remove
11 // this implementation if possible.
17 func (p *printer) writeType(this *types.Package, typ types.Type) {
18 p.writeTypeInternal(this, typ, make([]types.Type, 8))
21 // From go/types - leave for now to ease back-porting this code.
22 const GcCompatibilityMode = false
24 func (p *printer) writeTypeInternal(this *types.Package, typ types.Type, visited []types.Type) {
25 // Theoretically, this is a quadratic lookup algorithm, but in
26 // practice deeply nested composite types with unnamed component
27 // types are uncommon. This code is likely more efficient than
29 for _, t := range visited {
31 p.printf("○%T", typ) // cycle to typ
35 visited = append(visited, typ)
37 switch t := typ.(type) {
42 if t.Kind() == types.UnsafePointer {
45 if GcCompatibilityMode {
46 // forget the alias names
49 t = types.Typ[types.Uint8]
51 t = types.Typ[types.Int32]
57 p.printf("[%d]", t.Len())
58 p.writeTypeInternal(this, t.Elem(), visited)
62 p.writeTypeInternal(this, t.Elem(), visited)
73 for i := 0; i < n; i++ {
76 p.printf("%s ", f.Name())
78 p.writeTypeInternal(this, f.Type(), visited)
79 if tag := t.Tag(i); tag != "" {
89 p.writeTypeInternal(this, t.Elem(), visited)
92 p.writeTuple(this, t, false, visited)
94 case *types.Signature:
96 p.writeSignatureInternal(this, t, visited)
98 case *types.Interface:
99 // We write the source-level methods and embedded types rather
100 // than the actual method set since resolved method signatures
101 // may have non-printable cycles if parameters have anonymous
102 // interface types that (directly or indirectly) embed the
103 // current interface. For instance, consider the result type
107 // m() interface{ T }
112 p.print("interface{}")
116 p.print("interface {\n")
118 if GcCompatibilityMode {
119 // print flattened interface
120 // (useful to compare against gc-generated interfaces)
121 for i := 0; i < n; i++ {
124 p.writeSignatureInternal(this, m.Type().(*types.Signature), visited)
128 // print explicit interface methods and embedded types
129 for i, n := 0, t.NumExplicitMethods(); i < n; i++ {
130 m := t.ExplicitMethod(i)
132 p.writeSignatureInternal(this, m.Type().(*types.Signature), visited)
135 for i, n := 0, t.NumEmbeddeds(); i < n; i++ {
136 typ := t.EmbeddedType(i)
137 p.writeTypeInternal(this, typ, visited)
146 p.writeTypeInternal(this, t.Key(), visited)
148 p.writeTypeInternal(this, t.Elem(), visited)
156 // chan (<-chan T) requires parentheses
157 if c, _ := t.Elem().(*types.Chan); c != nil && c.Dir() == types.RecvOnly {
171 p.writeTypeInternal(this, t.Elem(), visited)
177 s := "<Named w/o object>"
178 if obj := t.Obj(); obj != nil {
179 if pkg := obj.Pkg(); pkg != nil {
184 // TODO(gri): function-local named types should be displayed
185 // differently from named types at package level to avoid
193 // For externally defined implementations of Type.
198 func (p *printer) writeTuple(this *types.Package, tup *types.Tuple, variadic bool, visited []types.Type) {
200 for i, n := 0, tup.Len(); i < n; i++ {
205 if name := v.Name(); name != "" {
210 if variadic && i == n-1 {
212 typ = typ.(*types.Slice).Elem()
214 p.writeTypeInternal(this, typ, visited)
219 func (p *printer) writeSignature(this *types.Package, sig *types.Signature) {
220 p.writeSignatureInternal(this, sig, make([]types.Type, 8))
223 func (p *printer) writeSignatureInternal(this *types.Package, sig *types.Signature, visited []types.Type) {
224 p.writeTuple(this, sig.Params(), sig.Variadic(), visited)
234 if n == 1 && res.At(0).Name() == "" {
235 // single unnamed result
236 p.writeTypeInternal(this, res.At(0).Type(), visited)
240 // multiple or named result(s)
241 p.writeTuple(this, res, false, visited)