...
1
2
3
4
5
6
7
8
9
10 package types2_test
11
12
13
14
15
16
17
18 import (
19 "cmd/compile/internal/syntax"
20 "cmd/compile/internal/types2"
21 "fmt"
22 "log"
23 "regexp"
24 "slices"
25 "strings"
26 )
27
28
29
30 func ExampleScope() {
31
32 var files []*syntax.File
33 for _, src := range []string{
34 `package main
35 import "fmt"
36 func main() {
37 freezing := FToC(-18)
38 fmt.Println(freezing, Boiling) }
39 `,
40 `package main
41 import "fmt"
42 type Celsius float64
43 func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
44 func FToC(f float64) Celsius { return Celsius(f - 32 / 9 * 5) }
45 const Boiling Celsius = 100
46 func Unused() { {}; {{ var x int; _ = x }} } // make sure empty block scopes get printed
47 `,
48 } {
49 files = append(files, mustParse(src))
50 }
51
52
53
54
55 conf := types2.Config{Importer: defaultImporter()}
56 pkg, err := conf.Check("temperature", files, nil)
57 if err != nil {
58 log.Fatal(err)
59 }
60
61
62
63 var buf strings.Builder
64 pkg.Scope().WriteTo(&buf, 0, true)
65 rx := regexp.MustCompile(` 0x[a-fA-F\d]*`)
66 fmt.Println(rx.ReplaceAllString(buf.String(), ""))
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 }
101
102
103
104
105 func ExampleInfo() {
106
107 const input = `
108 package fib
109
110 type S string
111
112 var a, b, c = len(b), S(c), "hello"
113
114 func fib(x int) int {
115 if x < 2 {
116 return x
117 }
118 return fib(x-1) - fib(x-2)
119 }`
120
121
122
123 info := types2.Info{
124 Types: make(map[syntax.Expr]types2.TypeAndValue),
125 Defs: make(map[*syntax.Name]types2.Object),
126 Uses: make(map[*syntax.Name]types2.Object),
127 }
128 pkg := mustTypecheck(input, nil, &info)
129
130
131 fmt.Printf("InitOrder: %v\n\n", info.InitOrder)
132
133
134
135 fmt.Println("Defs and Uses of each named object:")
136 usesByObj := make(map[types2.Object][]string)
137 for id, obj := range info.Uses {
138 posn := id.Pos()
139 lineCol := fmt.Sprintf("%d:%d", posn.Line(), posn.Col())
140 usesByObj[obj] = append(usesByObj[obj], lineCol)
141 }
142 var items []string
143 for obj, uses := range usesByObj {
144 slices.Sort(uses)
145 item := fmt.Sprintf("%s:\n defined at %s\n used at %s",
146 types2.ObjectString(obj, types2.RelativeTo(pkg)),
147 obj.Pos(),
148 strings.Join(uses, ", "))
149 items = append(items, item)
150 }
151 slices.Sort(items)
152 fmt.Println(strings.Join(items, "\n"))
153 fmt.Println()
154
155 fmt.Println("Types and Values of each expression:")
156 items = nil
157 for expr, tv := range info.Types {
158 var buf strings.Builder
159 posn := syntax.StartPos(expr)
160 tvstr := tv.Type.String()
161 if tv.Value != nil {
162 tvstr += " = " + tv.Value.String()
163 }
164
165 fmt.Fprintf(&buf, "%2d:%2d | %-19s | %-7s : %s",
166 posn.Line(), posn.Col(), types2.ExprString(expr),
167 mode(tv), tvstr)
168 items = append(items, buf.String())
169 }
170 slices.Sort(items)
171 fmt.Println(strings.Join(items, "\n"))
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 }
229
230 func mode(tv types2.TypeAndValue) string {
231 switch {
232 case tv.IsVoid():
233 return "void"
234 case tv.IsType():
235 return "type"
236 case tv.IsBuiltin():
237 return "builtin"
238 case tv.IsNil():
239 return "nil"
240 case tv.Assignable():
241 if tv.Addressable() {
242 return "var"
243 }
244 return "mapindex"
245 case tv.IsValue():
246 return "value"
247 default:
248 return "unknown"
249 }
250 }
251
View as plain text