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