Source file
src/go/types/object.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "bytes"
11 "fmt"
12 "go/constant"
13 "go/token"
14 "unicode"
15 "unicode/utf8"
16 )
17
18
19
20
21 type Object interface {
22 Parent() *Scope
23 Pos() token.Pos
24 Pkg() *Package
25 Name() string
26 Type() Type
27 Exported() bool
28 Id() string
29
30
31 String() string
32
33
34
35
36
37 order() uint32
38
39
40 color() color
41
42
43 setType(Type)
44
45
46 setOrder(uint32)
47
48
49 setColor(color color)
50
51
52 setParent(*Scope)
53
54
55 sameId(pkg *Package, name string) bool
56
57
58 scopePos() token.Pos
59
60
61 setScopePos(pos token.Pos)
62 }
63
64 func isExported(name string) bool {
65 ch, _ := utf8.DecodeRuneInString(name)
66 return unicode.IsUpper(ch)
67 }
68
69
70
71 func Id(pkg *Package, name string) string {
72 if isExported(name) {
73 return name
74 }
75
76
77
78
79
80 path := "_"
81
82
83 if pkg != nil && pkg.path != "" {
84 path = pkg.path
85 }
86 return path + "." + name
87 }
88
89
90 type object struct {
91 parent *Scope
92 pos token.Pos
93 pkg *Package
94 name string
95 typ Type
96 order_ uint32
97 color_ color
98 scopePos_ token.Pos
99 }
100
101
102 type color uint32
103
104
105
106 const (
107 white color = iota
108 black
109 grey
110 )
111
112 func (c color) String() string {
113 switch c {
114 case white:
115 return "white"
116 case black:
117 return "black"
118 default:
119 return "grey"
120 }
121 }
122
123
124
125 func colorFor(t Type) color {
126 if t != nil {
127 return black
128 }
129 return white
130 }
131
132
133
134 func (obj *object) Parent() *Scope { return obj.parent }
135
136
137 func (obj *object) Pos() token.Pos { return obj.pos }
138
139
140
141 func (obj *object) Pkg() *Package { return obj.pkg }
142
143
144 func (obj *object) Name() string { return obj.name }
145
146
147 func (obj *object) Type() Type { return obj.typ }
148
149
150
151
152 func (obj *object) Exported() bool { return isExported(obj.name) }
153
154
155 func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
156
157 func (obj *object) String() string { panic("abstract") }
158 func (obj *object) order() uint32 { return obj.order_ }
159 func (obj *object) color() color { return obj.color_ }
160 func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
161
162 func (obj *object) setParent(parent *Scope) { obj.parent = parent }
163 func (obj *object) setType(typ Type) { obj.typ = typ }
164 func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order }
165 func (obj *object) setColor(color color) { assert(color != white); obj.color_ = color }
166 func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
167
168 func (obj *object) sameId(pkg *Package, name string) bool {
169
170
171
172
173 if name != obj.name {
174 return false
175 }
176
177 if obj.Exported() {
178 return true
179 }
180
181
182
183 if pkg == nil || obj.pkg == nil {
184 return pkg == obj.pkg
185 }
186
187 return pkg.path == obj.pkg.path
188 }
189
190
191
192
193
194
195 func (a *object) less(b *object) bool {
196 if a == b {
197 return false
198 }
199
200
201 if a == nil {
202 return true
203 }
204 if b == nil {
205 return false
206 }
207
208
209 ea := isExported(a.name)
210 eb := isExported(b.name)
211 if ea != eb {
212 return ea
213 }
214
215
216 if a.name != b.name {
217 return a.name < b.name
218 }
219 if !ea {
220 return a.pkg.path < b.pkg.path
221 }
222
223 return false
224 }
225
226
227
228 type PkgName struct {
229 object
230 imported *Package
231 used bool
232 }
233
234
235
236 func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
237 return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
238 }
239
240
241
242 func (obj *PkgName) Imported() *Package { return obj.imported }
243
244
245 type Const struct {
246 object
247 val constant.Value
248 }
249
250
251
252 func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
253 return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, val}
254 }
255
256
257 func (obj *Const) Val() constant.Value { return obj.val }
258
259 func (*Const) isDependency() {}
260
261
262 type TypeName struct {
263 object
264 }
265
266
267
268
269
270
271
272
273 func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
274 return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
275 }
276
277
278
279 func _NewTypeNameLazy(pos token.Pos, pkg *Package, name string, load func(named *Named) (tparams []*TypeParam, underlying Type, methods []*Func)) *TypeName {
280 obj := NewTypeName(pos, pkg, name, nil)
281 NewNamed(obj, nil, nil).loader = load
282 return obj
283 }
284
285
286 func (obj *TypeName) IsAlias() bool {
287 switch t := obj.typ.(type) {
288 case nil:
289 return false
290
291
292 case *Basic:
293
294 if obj.pkg == Unsafe {
295 return false
296 }
297
298
299
300
301
302
303 return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
304 case *Named:
305 return obj != t.obj
306 case *TypeParam:
307 return obj != t.obj
308 default:
309 return true
310 }
311 }
312
313
314 type Var struct {
315 object
316 embedded bool
317 isField bool
318 used bool
319 origin *Var
320 }
321
322
323
324 func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
325 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
326 }
327
328
329 func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
330 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true}
331 }
332
333
334
335
336 func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
337 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, embedded: embedded, isField: true}
338 }
339
340
341
342 func (obj *Var) Anonymous() bool { return obj.embedded }
343
344
345 func (obj *Var) Embedded() bool { return obj.embedded }
346
347
348 func (obj *Var) IsField() bool { return obj.isField }
349
350
351
352
353
354
355
356
357 func (obj *Var) Origin() *Var {
358 if obj.origin != nil {
359 return obj.origin
360 }
361 return obj
362 }
363
364 func (*Var) isDependency() {}
365
366
367
368
369 type Func struct {
370 object
371 hasPtrRecv_ bool
372 origin *Func
373 }
374
375
376
377 func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
378
379 var typ Type
380 if sig != nil {
381 typ = sig
382 }
383 return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false, nil}
384 }
385
386
387
388 func (obj *Func) FullName() string {
389 var buf bytes.Buffer
390 writeFuncName(&buf, obj, nil)
391 return buf.String()
392 }
393
394
395
396
397 func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
398
399
400
401
402
403
404
405
406 func (obj *Func) Origin() *Func {
407 if obj.origin != nil {
408 return obj.origin
409 }
410 return obj
411 }
412
413
414
415
416
417 func (obj *Func) Pkg() *Package { return obj.object.Pkg() }
418
419
420 func (obj *Func) hasPtrRecv() bool {
421
422
423
424
425 if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
426 _, isPtr := deref(sig.recv.typ)
427 return isPtr
428 }
429
430
431
432
433
434
435 return obj.hasPtrRecv_
436 }
437
438 func (*Func) isDependency() {}
439
440
441
442 type Label struct {
443 object
444 used bool
445 }
446
447
448 func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
449 return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
450 }
451
452
453
454 type Builtin struct {
455 object
456 id builtinId
457 }
458
459 func newBuiltin(id builtinId) *Builtin {
460 return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
461 }
462
463
464 type Nil struct {
465 object
466 }
467
468 func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
469 var tname *TypeName
470 typ := obj.Type()
471
472 switch obj := obj.(type) {
473 case *PkgName:
474 fmt.Fprintf(buf, "package %s", obj.Name())
475 if path := obj.imported.path; path != "" && path != obj.name {
476 fmt.Fprintf(buf, " (%q)", path)
477 }
478 return
479
480 case *Const:
481 buf.WriteString("const")
482
483 case *TypeName:
484 tname = obj
485 buf.WriteString("type")
486 if isTypeParam(typ) {
487 buf.WriteString(" parameter")
488 }
489
490 case *Var:
491 if obj.isField {
492 buf.WriteString("field")
493 } else {
494 buf.WriteString("var")
495 }
496
497 case *Func:
498 buf.WriteString("func ")
499 writeFuncName(buf, obj, qf)
500 if typ != nil {
501 WriteSignature(buf, typ.(*Signature), qf)
502 }
503 return
504
505 case *Label:
506 buf.WriteString("label")
507 typ = nil
508
509 case *Builtin:
510 buf.WriteString("builtin")
511 typ = nil
512
513 case *Nil:
514 buf.WriteString("nil")
515 return
516
517 default:
518 panic(fmt.Sprintf("writeObject(%T)", obj))
519 }
520
521 buf.WriteByte(' ')
522
523
524 if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
525 buf.WriteString(packagePrefix(obj.Pkg(), qf))
526 }
527 buf.WriteString(obj.Name())
528
529 if typ == nil {
530 return
531 }
532
533 if tname != nil {
534 switch t := typ.(type) {
535 case *Basic:
536
537
538 return
539 case *Named:
540 if t.TypeParams().Len() > 0 {
541 newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
542 }
543 }
544 if tname.IsAlias() {
545 buf.WriteString(" =")
546 } else if t, _ := typ.(*TypeParam); t != nil {
547 typ = t.bound
548 } else {
549
550 typ = under(typ)
551 }
552 }
553
554
555
556
557 if obj == universeAny {
558 assert(Identical(typ, &emptyInterface))
559 typ = &emptyInterface
560 }
561
562 buf.WriteByte(' ')
563 WriteType(buf, typ, qf)
564 }
565
566 func packagePrefix(pkg *Package, qf Qualifier) string {
567 if pkg == nil {
568 return ""
569 }
570 var s string
571 if qf != nil {
572 s = qf(pkg)
573 } else {
574 s = pkg.Path()
575 }
576 if s != "" {
577 s += "."
578 }
579 return s
580 }
581
582
583
584
585 func ObjectString(obj Object, qf Qualifier) string {
586 var buf bytes.Buffer
587 writeObject(&buf, obj, qf)
588 return buf.String()
589 }
590
591 func (obj *PkgName) String() string { return ObjectString(obj, nil) }
592 func (obj *Const) String() string { return ObjectString(obj, nil) }
593 func (obj *TypeName) String() string { return ObjectString(obj, nil) }
594 func (obj *Var) String() string { return ObjectString(obj, nil) }
595 func (obj *Func) String() string { return ObjectString(obj, nil) }
596 func (obj *Label) String() string { return ObjectString(obj, nil) }
597 func (obj *Builtin) String() string { return ObjectString(obj, nil) }
598 func (obj *Nil) String() string { return ObjectString(obj, nil) }
599
600 func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
601 if f.typ != nil {
602 sig := f.typ.(*Signature)
603 if recv := sig.Recv(); recv != nil {
604 buf.WriteByte('(')
605 if _, ok := recv.Type().(*Interface); ok {
606
607
608
609
610 buf.WriteString("interface")
611 } else {
612 WriteType(buf, recv.Type(), qf)
613 }
614 buf.WriteByte(')')
615 buf.WriteByte('.')
616 } else if f.pkg != nil {
617 buf.WriteString(packagePrefix(f.pkg, qf))
618 }
619 }
620 buf.WriteString(f.name)
621 }
622
View as plain text