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