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