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