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 *Named) (tparams []*TypeParam, underlying Type, methods []*Func)) *TypeName {
297 obj := NewTypeName(pos, pkg, name, nil)
298 NewNamed(obj, nil, nil).loader = load
299 return obj
300 }
301
302
303 func (obj *TypeName) IsAlias() bool {
304 switch t := obj.typ.(type) {
305 case nil:
306 return false
307
308
309 case *Basic:
310
311 if obj.pkg == Unsafe {
312 return false
313 }
314
315
316
317
318
319
320 return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
321 case *Named:
322 return obj != t.obj
323 case *TypeParam:
324 return obj != t.obj
325 default:
326 return true
327 }
328 }
329
330
331 type Var struct {
332 object
333 origin *Var
334 kind VarKind
335 embedded bool
336 }
337
338
339 type VarKind uint8
340
341 const (
342 _ VarKind = iota
343 PackageVar
344 LocalVar
345 RecvVar
346 ParamVar
347 ResultVar
348 FieldVar
349 )
350
351 var varKindNames = [...]string{
352 0: "VarKind(0)",
353 PackageVar: "PackageVar",
354 LocalVar: "LocalVar",
355 RecvVar: "RecvVar",
356 ParamVar: "ParamVar",
357 ResultVar: "ResultVar",
358 FieldVar: "FieldVar",
359 }
360
361 func (kind VarKind) String() string {
362 if 0 <= kind && int(kind) < len(varKindNames) {
363 return varKindNames[kind]
364 }
365 return fmt.Sprintf("VarKind(%d)", kind)
366 }
367
368
369 func (v *Var) Kind() VarKind { return v.kind }
370
371
372
373 func (v *Var) SetKind(kind VarKind) { v.kind = kind }
374
375
376
377
378
379
380 func NewVar(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
381 return newVar(PackageVar, pos, pkg, name, typ)
382 }
383
384
385
386
387
388 func NewParam(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
389 return newVar(ParamVar, pos, pkg, name, typ)
390 }
391
392
393
394
395 func NewField(pos syntax.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
396 v := newVar(FieldVar, pos, pkg, name, typ)
397 v.embedded = embedded
398 return v
399 }
400
401
402
403 func newVar(kind VarKind, pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
404 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, kind: kind}
405 }
406
407
408
409 func (obj *Var) Anonymous() bool { return obj.embedded }
410
411
412 func (obj *Var) Embedded() bool { return obj.embedded }
413
414
415 func (obj *Var) IsField() bool { return obj.kind == FieldVar }
416
417
418
419
420
421
422
423
424 func (obj *Var) Origin() *Var {
425 if obj.origin != nil {
426 return obj.origin
427 }
428 return obj
429 }
430
431 func (*Var) isDependency() {}
432
433
434
435
436 type Func struct {
437 object
438 hasPtrRecv_ bool
439 origin *Func
440 }
441
442
443
444 func NewFunc(pos syntax.Pos, pkg *Package, name string, sig *Signature) *Func {
445 var typ Type
446 if sig != nil {
447 typ = sig
448 } else {
449
450
451
452
453 }
454 return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false, nil}
455 }
456
457
458 func (obj *Func) Signature() *Signature {
459 if obj.typ != nil {
460 return obj.typ.(*Signature)
461 }
462
463
464
465
466
467
468
469
470 return new(Signature)
471 }
472
473
474
475 func (obj *Func) FullName() string {
476 var buf bytes.Buffer
477 writeFuncName(&buf, obj, nil)
478 return buf.String()
479 }
480
481
482
483
484 func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
485
486
487
488
489
490
491
492
493 func (obj *Func) Origin() *Func {
494 if obj.origin != nil {
495 return obj.origin
496 }
497 return obj
498 }
499
500
501
502
503
504 func (obj *Func) Pkg() *Package { return obj.object.Pkg() }
505
506
507 func (obj *Func) hasPtrRecv() bool {
508
509
510
511
512 if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
513 _, isPtr := deref(sig.recv.typ)
514 return isPtr
515 }
516
517
518
519
520
521
522 return obj.hasPtrRecv_
523 }
524
525 func (*Func) isDependency() {}
526
527
528
529 type Label struct {
530 object
531 used bool
532 }
533
534
535 func NewLabel(pos syntax.Pos, pkg *Package, name string) *Label {
536 return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
537 }
538
539
540
541 type Builtin struct {
542 object
543 id builtinId
544 }
545
546 func newBuiltin(id builtinId) *Builtin {
547 return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
548 }
549
550
551 type Nil struct {
552 object
553 }
554
555 func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
556 var tname *TypeName
557 typ := obj.Type()
558
559 switch obj := obj.(type) {
560 case *PkgName:
561 fmt.Fprintf(buf, "package %s", obj.Name())
562 if path := obj.imported.path; path != "" && path != obj.name {
563 fmt.Fprintf(buf, " (%q)", path)
564 }
565 return
566
567 case *Const:
568 buf.WriteString("const")
569
570 case *TypeName:
571 tname = obj
572 buf.WriteString("type")
573 if isTypeParam(typ) {
574 buf.WriteString(" parameter")
575 }
576
577 case *Var:
578 if obj.IsField() {
579 buf.WriteString("field")
580 } else {
581 buf.WriteString("var")
582 }
583
584 case *Func:
585 buf.WriteString("func ")
586 writeFuncName(buf, obj, qf)
587 if typ != nil {
588 WriteSignature(buf, typ.(*Signature), qf)
589 }
590 return
591
592 case *Label:
593 buf.WriteString("label")
594 typ = nil
595
596 case *Builtin:
597 buf.WriteString("builtin")
598 typ = nil
599
600 case *Nil:
601 buf.WriteString("nil")
602 return
603
604 default:
605 panic(fmt.Sprintf("writeObject(%T)", obj))
606 }
607
608 buf.WriteByte(' ')
609
610
611 if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
612 buf.WriteString(packagePrefix(obj.Pkg(), qf))
613 }
614 buf.WriteString(obj.Name())
615
616 if typ == nil {
617 return
618 }
619
620 if tname != nil {
621 switch t := typ.(type) {
622 case *Basic:
623
624
625 return
626 case genericType:
627 if t.TypeParams().Len() > 0 {
628 newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
629 }
630 }
631 if tname.IsAlias() {
632 buf.WriteString(" =")
633 if alias, ok := typ.(*Alias); ok {
634 typ = alias.fromRHS
635 }
636 } else if t, _ := typ.(*TypeParam); t != nil {
637 typ = t.bound
638 } else {
639
640
641 typ = under(typ)
642 }
643 }
644
645
646
647
648 if obj.Name() == "any" && obj.Parent() == Universe {
649 assert(Identical(typ, &emptyInterface))
650 typ = &emptyInterface
651 }
652
653 buf.WriteByte(' ')
654 WriteType(buf, typ, qf)
655 }
656
657 func packagePrefix(pkg *Package, qf Qualifier) string {
658 if pkg == nil {
659 return ""
660 }
661 var s string
662 if qf != nil {
663 s = qf(pkg)
664 } else {
665 s = pkg.Path()
666 }
667 if s != "" {
668 s += "."
669 }
670 return s
671 }
672
673
674
675
676 func ObjectString(obj Object, qf Qualifier) string {
677 var buf bytes.Buffer
678 writeObject(&buf, obj, qf)
679 return buf.String()
680 }
681
682 func (obj *PkgName) String() string { return ObjectString(obj, nil) }
683 func (obj *Const) String() string { return ObjectString(obj, nil) }
684 func (obj *TypeName) String() string { return ObjectString(obj, nil) }
685 func (obj *Var) String() string { return ObjectString(obj, nil) }
686 func (obj *Func) String() string { return ObjectString(obj, nil) }
687 func (obj *Label) String() string { return ObjectString(obj, nil) }
688 func (obj *Builtin) String() string { return ObjectString(obj, nil) }
689 func (obj *Nil) String() string { return ObjectString(obj, nil) }
690
691 func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
692 if f.typ != nil {
693 sig := f.typ.(*Signature)
694 if recv := sig.Recv(); recv != nil {
695 buf.WriteByte('(')
696 if _, ok := recv.Type().(*Interface); ok {
697
698
699
700
701 buf.WriteString("interface")
702 } else {
703 WriteType(buf, recv.Type(), qf)
704 }
705 buf.WriteByte(')')
706 buf.WriteByte('.')
707 } else if f.pkg != nil {
708 buf.WriteString(packagePrefix(f.pkg, qf))
709 }
710 }
711 buf.WriteString(f.name)
712 }
713
View as plain text