Source file src/go/types/object.go
1
2
3
4
5 package types
6
7 import (
8 "bytes"
9 "fmt"
10 "go/constant"
11 "go/token"
12 )
13
14
15
16
17
18 type Object interface {
19 Parent() *Scope
20 Pos() token.Pos
21 Pkg() *Package
22 Name() string
23 Type() Type
24 Exported() bool
25 Id() string
26
27
28 String() string
29
30
31
32
33
34 order() uint32
35
36
37 color() color
38
39
40 setOrder(uint32)
41
42
43 setColor(color color)
44
45
46 setParent(*Scope)
47
48
49 sameId(pkg *Package, name string) bool
50
51
52 scopePos() token.Pos
53
54
55 setScopePos(pos token.Pos)
56 }
57
58
59
60 func Id(pkg *Package, name string) string {
61 if token.IsExported(name) {
62 return name
63 }
64
65
66
67
68
69 path := "_"
70
71
72 if pkg != nil && pkg.path != "" {
73 path = pkg.path
74 }
75 return path + "." + name
76 }
77
78
79 type object struct {
80 parent *Scope
81 pos token.Pos
82 pkg *Package
83 name string
84 typ Type
85 order_ uint32
86 color_ color
87 scopePos_ token.Pos
88 }
89
90
91 type color uint32
92
93
94
95 const (
96 white color = iota
97 black
98 grey
99 )
100
101 func (c color) String() string {
102 switch c {
103 case white:
104 return "white"
105 case black:
106 return "black"
107 default:
108 return "grey"
109 }
110 }
111
112
113
114 func colorFor(t Type) color {
115 if t != nil {
116 return black
117 }
118 return white
119 }
120
121
122
123 func (obj *object) Parent() *Scope { return obj.parent }
124
125
126 func (obj *object) Pos() token.Pos { return obj.pos }
127
128
129
130 func (obj *object) Pkg() *Package { return obj.pkg }
131
132
133 func (obj *object) Name() string { return obj.name }
134
135
136 func (obj *object) Type() Type { return obj.typ }
137
138
139
140
141 func (obj *object) Exported() bool { return token.IsExported(obj.name) }
142
143
144 func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
145
146 func (obj *object) String() string { panic("abstract") }
147 func (obj *object) order() uint32 { return obj.order_ }
148 func (obj *object) color() color { return obj.color_ }
149 func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
150
151 func (obj *object) setParent(parent *Scope) { obj.parent = parent }
152 func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order }
153 func (obj *object) setColor(color color) { assert(color != white); obj.color_ = color }
154 func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
155
156 func (obj *object) sameId(pkg *Package, name string) bool {
157
158
159
160
161 if name != obj.name {
162 return false
163 }
164
165 if obj.Exported() {
166 return true
167 }
168
169
170
171 if pkg == nil || obj.pkg == nil {
172 return pkg == obj.pkg
173 }
174
175 return pkg.path == obj.pkg.path
176 }
177
178
179
180 type PkgName struct {
181 object
182 imported *Package
183 used bool
184 }
185
186
187
188 func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
189 return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, token.NoPos}, imported, false}
190 }
191
192
193
194 func (obj *PkgName) Imported() *Package { return obj.imported }
195
196
197 type Const struct {
198 object
199 val constant.Value
200 }
201
202
203
204 func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
205 return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, val}
206 }
207
208
209 func (obj *Const) Val() constant.Value { return obj.val }
210
211 func (*Const) isDependency() {}
212
213
214 type TypeName struct {
215 object
216 }
217
218
219
220
221
222
223
224
225 func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
226 return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}}
227 }
228
229
230 func (obj *TypeName) IsAlias() bool {
231 switch t := obj.typ.(type) {
232 case nil:
233 return false
234 case *Basic:
235
236 if obj.pkg == Unsafe {
237 return false
238 }
239
240
241
242
243
244
245 return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
246 case *Named:
247 return obj != t.obj
248 default:
249 return true
250 }
251 }
252
253
254 type Var struct {
255 object
256 embedded bool
257 isField bool
258 used bool
259 }
260
261
262
263 func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
264 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}}
265 }
266
267
268 func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
269 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, used: true}
270 }
271
272
273
274
275 func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
276 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, embedded: embedded, isField: true}
277 }
278
279
280
281 func (obj *Var) Anonymous() bool { return obj.embedded }
282
283
284 func (obj *Var) Embedded() bool { return obj.embedded }
285
286
287 func (obj *Var) IsField() bool { return obj.isField }
288
289 func (*Var) isDependency() {}
290
291
292
293
294 type Func struct {
295 object
296 hasPtrRecv bool
297 }
298
299
300
301 func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
302
303 var typ Type
304 if sig != nil {
305 typ = sig
306 }
307 return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, false}
308 }
309
310
311
312 func (obj *Func) FullName() string {
313 var buf bytes.Buffer
314 writeFuncName(&buf, obj, nil)
315 return buf.String()
316 }
317
318
319 func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
320
321 func (*Func) isDependency() {}
322
323
324
325 type Label struct {
326 object
327 used bool
328 }
329
330
331 func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
332 return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
333 }
334
335
336
337 type Builtin struct {
338 object
339 id builtinId
340 }
341
342 func newBuiltin(id builtinId) *Builtin {
343 return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
344 }
345
346
347 type Nil struct {
348 object
349 }
350
351 func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
352 var tname *TypeName
353 typ := obj.Type()
354
355 switch obj := obj.(type) {
356 case *PkgName:
357 fmt.Fprintf(buf, "package %s", obj.Name())
358 if path := obj.imported.path; path != "" && path != obj.name {
359 fmt.Fprintf(buf, " (%q)", path)
360 }
361 return
362
363 case *Const:
364 buf.WriteString("const")
365
366 case *TypeName:
367 tname = obj
368 buf.WriteString("type")
369
370 case *Var:
371 if obj.isField {
372 buf.WriteString("field")
373 } else {
374 buf.WriteString("var")
375 }
376
377 case *Func:
378 buf.WriteString("func ")
379 writeFuncName(buf, obj, qf)
380 if typ != nil {
381 WriteSignature(buf, typ.(*Signature), qf)
382 }
383 return
384
385 case *Label:
386 buf.WriteString("label")
387 typ = nil
388
389 case *Builtin:
390 buf.WriteString("builtin")
391 typ = nil
392
393 case *Nil:
394 buf.WriteString("nil")
395 return
396
397 default:
398 panic(fmt.Sprintf("writeObject(%T)", obj))
399 }
400
401 buf.WriteByte(' ')
402
403
404 if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
405 writePackage(buf, obj.Pkg(), qf)
406 }
407 buf.WriteString(obj.Name())
408
409 if typ == nil {
410 return
411 }
412
413 if tname != nil {
414
415
416
417 if _, ok := typ.(*Basic); ok {
418 return
419 }
420 if tname.IsAlias() {
421 buf.WriteString(" =")
422 } else {
423 typ = typ.Underlying()
424 }
425 }
426
427 buf.WriteByte(' ')
428 WriteType(buf, typ, qf)
429 }
430
431 func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
432 if pkg == nil {
433 return
434 }
435 var s string
436 if qf != nil {
437 s = qf(pkg)
438 } else {
439 s = pkg.Path()
440 }
441 if s != "" {
442 buf.WriteString(s)
443 buf.WriteByte('.')
444 }
445 }
446
447
448
449
450 func ObjectString(obj Object, qf Qualifier) string {
451 var buf bytes.Buffer
452 writeObject(&buf, obj, qf)
453 return buf.String()
454 }
455
456 func (obj *PkgName) String() string { return ObjectString(obj, nil) }
457 func (obj *Const) String() string { return ObjectString(obj, nil) }
458 func (obj *TypeName) String() string { return ObjectString(obj, nil) }
459 func (obj *Var) String() string { return ObjectString(obj, nil) }
460 func (obj *Func) String() string { return ObjectString(obj, nil) }
461 func (obj *Label) String() string { return ObjectString(obj, nil) }
462 func (obj *Builtin) String() string { return ObjectString(obj, nil) }
463 func (obj *Nil) String() string { return ObjectString(obj, nil) }
464
465 func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
466 if f.typ != nil {
467 sig := f.typ.(*Signature)
468 if recv := sig.Recv(); recv != nil {
469 buf.WriteByte('(')
470 if _, ok := recv.Type().(*Interface); ok {
471
472
473
474
475 buf.WriteString("interface")
476 } else {
477 WriteType(buf, recv.Type(), qf)
478 }
479 buf.WriteByte(')')
480 buf.WriteByte('.')
481 } else if f.pkg != nil {
482 writePackage(buf, f.pkg, qf)
483 }
484 }
485 buf.WriteString(f.name)
486 }
487
View as plain text