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