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