Source file
src/go/types/format.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "bytes"
11 "fmt"
12 "go/ast"
13 "go/token"
14 "strconv"
15 "strings"
16 )
17
18 func sprintf(fset *token.FileSet, qf Qualifier, tpSubscripts bool, format string, args ...any) string {
19 for i, arg := range args {
20 switch a := arg.(type) {
21 case nil:
22 arg = "<nil>"
23 case operand:
24 panic("got operand instead of *operand")
25 case *operand:
26 arg = operandString(a, qf)
27 case token.Pos:
28 if fset != nil {
29 arg = fset.Position(a).String()
30 }
31 case ast.Expr:
32 arg = ExprString(a)
33 case []ast.Expr:
34 var buf bytes.Buffer
35 buf.WriteByte('[')
36 writeExprList(&buf, a)
37 buf.WriteByte(']')
38 arg = buf.String()
39 case Object:
40 arg = ObjectString(a, qf)
41 case Type:
42 var buf bytes.Buffer
43 w := newTypeWriter(&buf, qf)
44 w.tpSubscripts = tpSubscripts
45 w.typ(a)
46 arg = buf.String()
47 case []Type:
48 var buf bytes.Buffer
49 w := newTypeWriter(&buf, qf)
50 w.tpSubscripts = tpSubscripts
51 buf.WriteByte('[')
52 for i, x := range a {
53 if i > 0 {
54 buf.WriteString(", ")
55 }
56 w.typ(x)
57 }
58 buf.WriteByte(']')
59 arg = buf.String()
60 case []*TypeParam:
61 var buf bytes.Buffer
62 w := newTypeWriter(&buf, qf)
63 w.tpSubscripts = tpSubscripts
64 buf.WriteByte('[')
65 for i, x := range a {
66 if i > 0 {
67 buf.WriteString(", ")
68 }
69 w.typ(x)
70 }
71 buf.WriteByte(']')
72 arg = buf.String()
73 }
74 args[i] = arg
75 }
76 return fmt.Sprintf(format, args...)
77 }
78
79
80 func (check *Checker) sprintf(format string, args ...any) string {
81 var fset *token.FileSet
82 var qf Qualifier
83 if check != nil {
84 fset = check.fset
85 qf = check.qualifier
86 }
87 return sprintf(fset, qf, false, format, args...)
88 }
89
90 func (check *Checker) trace(pos token.Pos, format string, args ...any) {
91 pos1 := check.fset.Position(pos)
92
93
94
95 w := ndigits(pos1.Line) + ndigits(pos1.Column)
96 pad := " "[:max(5-w, 0)]
97 fmt.Printf("%s%s: %s%s\n",
98 pos1,
99 pad,
100 strings.Repeat(". ", check.indent),
101 sprintf(check.fset, check.qualifier, true, format, args...),
102 )
103 }
104
105
106
107
108 func ndigits(x int) int {
109 switch {
110 case x < 10:
111 return 1
112 case x < 100:
113 return 2
114 default:
115 return 3
116 }
117 }
118
119
120 func (check *Checker) dump(format string, args ...any) {
121 fmt.Println(sprintf(check.fset, check.qualifier, true, format, args...))
122 }
123
124 func (check *Checker) qualifier(pkg *Package) string {
125
126 if pkg != check.pkg {
127 if check.pkgPathMap == nil {
128 check.pkgPathMap = make(map[string]map[string]bool)
129 check.seenPkgMap = make(map[*Package]bool)
130 check.markImports(check.pkg)
131 }
132
133 if len(check.pkgPathMap[pkg.name]) > 1 {
134 return strconv.Quote(pkg.path)
135 }
136 return pkg.name
137 }
138 return ""
139 }
140
141
142
143 func (check *Checker) markImports(pkg *Package) {
144 if check.seenPkgMap[pkg] {
145 return
146 }
147 check.seenPkgMap[pkg] = true
148
149 forName, ok := check.pkgPathMap[pkg.name]
150 if !ok {
151 forName = make(map[string]bool)
152 check.pkgPathMap[pkg.name] = forName
153 }
154 forName[pkg.path] = true
155
156 for _, imp := range pkg.imports {
157 check.markImports(imp)
158 }
159 }
160
161
162 func stripAnnotations(s string) string {
163 var buf strings.Builder
164 for _, r := range s {
165
166 if r < '₀' || '₀'+10 <= r {
167 buf.WriteRune(r)
168 }
169 }
170 if buf.Len() < len(s) {
171 return buf.String()
172 }
173 return s
174 }
175
View as plain text