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