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