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